diff --git a/algorithms/src/main/java/com/baeldung/algorithms/BinarySearch.java b/algorithms/src/main/java/com/baeldung/algorithms/BinarySearch.java
new file mode 100644
index 0000000000..be4a9e578a
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/BinarySearch.java
@@ -0,0 +1,26 @@
+public class BinarySearch {
+
+ public int runBinarySearch() {
+ int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
+ int key = 6;
+
+ int low = 0;
+ int high = sortedArray.length - 1;
+ int index = Integer.MAX_VALUE;
+
+ while (low <= high) {
+
+ int mid = (low + high) / 2;
+
+ if (sortedArray[mid] < key) {
+ low = mid + 1;
+ } else if (sortedArray[mid] > key) {
+ high = mid - 1;
+ } else if (sortedArray[mid] == key) {
+ index = mid;
+ break;
+ }
+ }
+ return index;
+ }
+}
diff --git a/algorithms/src/test/java/algorithms/BinarySearchTest.java b/algorithms/src/test/java/algorithms/BinarySearchTest.java
new file mode 100644
index 0000000000..d53b074cc4
--- /dev/null
+++ b/algorithms/src/test/java/algorithms/BinarySearchTest.java
@@ -0,0 +1,14 @@
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class BinarySearchTest {
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ int expectedIndexForSearchKey = 7;
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearch());
+ }
+
+}
diff --git a/apache-shiro/.gitignore b/apache-shiro/.gitignore
new file mode 100644
index 0000000000..020cda4898
--- /dev/null
+++ b/apache-shiro/.gitignore
@@ -0,0 +1,4 @@
+
+/.idea/
+/target/
+/apache-shiro.iml
\ No newline at end of file
diff --git a/apache-shiro/README.md b/apache-shiro/README.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/apache-shiro/pom.xml b/apache-shiro/pom.xml
new file mode 100644
index 0000000000..97ed872a26
--- /dev/null
+++ b/apache-shiro/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ apache-shiro
+ 1.0-SNAPSHOT
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ 1.4.0
+ 1.2.17
+ 1.7.25
+
+
+
+
+ org.apache.shiro
+ shiro-core
+ ${apache-shiro-core-version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j-version}
+ runtime
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j-version}
+ runtime
+
+
+ log4j
+ log4j
+ ${log4j-version}
+ runtime
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.2
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-shiro/src/main/java/com/baeldung/Main.java b/apache-shiro/src/main/java/com/baeldung/Main.java
new file mode 100644
index 0000000000..5e341f251b
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/Main.java
@@ -0,0 +1,85 @@
+package com.baeldung;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.*;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.IniRealm;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Main {
+
+ private static final transient Logger log = LoggerFactory.getLogger(Main.class);
+
+ public static void main(String[] args) {
+
+ Realm realm = new MyCustomRealm();
+ SecurityManager securityManager = new DefaultSecurityManager(realm);
+
+ SecurityUtils.setSecurityManager(securityManager);
+ Subject currentUser = SecurityUtils.getSubject();
+
+ if (!currentUser.isAuthenticated()) {
+ UsernamePasswordToken token
+ = new UsernamePasswordToken("user", "password");
+ token.setRememberMe(true);
+ try {
+ currentUser.login(token);
+ } catch (UnknownAccountException uae) {
+ log.error("Username Not Found!", uae);
+ } catch (IncorrectCredentialsException ice) {
+ log.error("Invalid Credentials!", ice);
+ } catch (LockedAccountException lae) {
+ log.error("Your Account is Locked!", lae);
+ } catch (AuthenticationException ae) {
+ log.error("Unexpected Error!", ae);
+ }
+ }
+
+ log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
+
+ if (currentUser.hasRole("admin")) {
+ log.info("Welcome Admin");
+ } else if(currentUser.hasRole("editor")) {
+ log.info("Welcome, Editor!");
+ } else if(currentUser.hasRole("author")) {
+ log.info("Welcome, Author");
+ } else {
+ log.info("Welcome, Guest");
+ }
+
+ if(currentUser.isPermitted("articles:compose")) {
+ log.info("You can compose an article");
+ } else {
+ log.info("You are not permitted to compose an article!");
+ }
+
+ if(currentUser.isPermitted("articles:save")) {
+ log.info("You can save articles");
+ } else {
+ log.info("You can not save articles");
+ }
+
+ if(currentUser.isPermitted("articles:publish")) {
+ log.info("You can publish articles");
+ } else {
+ log.info("You can not publish articles");
+ }
+
+ Session session = currentUser.getSession();
+ session.setAttribute("key", "value");
+ String value = (String) session.getAttribute("key");
+ if (value.equals("value")) {
+ log.info("Retrieved the correct value! [" + value + "]");
+ }
+
+ currentUser.logout();
+
+ System.exit(0);
+ }
+
+}
diff --git a/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java b/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java
new file mode 100644
index 0000000000..8d792c76a5
--- /dev/null
+++ b/apache-shiro/src/main/java/com/baeldung/MyCustomRealm.java
@@ -0,0 +1,102 @@
+package com.baeldung;
+
+import org.apache.shiro.authc.*;
+import org.apache.shiro.authz.AuthorizationInfo;
+import org.apache.shiro.authz.SimpleAuthorizationInfo;
+import org.apache.shiro.realm.jdbc.JdbcRealm;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.*;
+
+public class MyCustomRealm extends JdbcRealm {
+
+ private Map credentials = new HashMap<>();
+ private Map> roles = new HashMap<>();
+ private Map> perm = new HashMap<>();
+
+ {
+ credentials.put("user", "password");
+ credentials.put("user2", "password2");
+ credentials.put("user3", "password3");
+
+ roles.put("user", new HashSet<>(Arrays.asList("admin")));
+ roles.put("user2", new HashSet<>(Arrays.asList("editor")));
+ roles.put("user3", new HashSet<>(Arrays.asList("author")));
+
+ perm.put("admin", new HashSet<>(Arrays.asList("*")));
+ perm.put("editor", new HashSet<>(Arrays.asList("articles:*")));
+ perm.put("author",
+ new HashSet<>(Arrays.asList("articles:compose",
+ "articles:save")));
+
+ }
+
+ @Override
+ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
+ throws AuthenticationException {
+
+ UsernamePasswordToken uToken = (UsernamePasswordToken) token;
+
+ if(uToken.getUsername() == null
+ || uToken.getUsername().isEmpty()
+ || !credentials.containsKey(uToken.getUsername())
+ ) {
+ throw new UnknownAccountException("username not found!");
+ }
+
+
+ return new SimpleAuthenticationInfo(
+ uToken.getUsername(), credentials.get(uToken.getUsername()),
+ getName());
+ }
+
+ @Override
+ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
+ Set roleNames = new HashSet<>();
+ Set permissions = new HashSet<>();
+
+ principals.forEach(p -> {
+ try {
+ Set roles = getRoleNamesForUser(null, (String) p);
+ roleNames.addAll(roles);
+ permissions.addAll(getPermissions(null, null,roles));
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ });
+
+ SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
+ info.setStringPermissions(permissions);
+ return info;
+ }
+
+ @Override
+ protected Set getRoleNamesForUser(Connection conn, String username) throws SQLException {
+ if(!roles.containsKey(username)) {
+ throw new SQLException("username not found!");
+ }
+
+ return roles.get(username);
+ }
+
+ @Override
+ protected Set getPermissions(Connection conn, String username, Collection roleNames) throws SQLException {
+ for (String role : roleNames) {
+ if (!perm.containsKey(role)) {
+ throw new SQLException("role not found!");
+ }
+ }
+
+ Set finalSet = new HashSet<>();
+ for (String role : roleNames) {
+ finalSet.addAll(perm.get(role));
+ }
+
+ return finalSet;
+ }
+
+}
diff --git a/apache-shiro/src/main/resources/log4j.properties b/apache-shiro/src/main/resources/log4j.properties
new file mode 100644
index 0000000000..897bf08221
--- /dev/null
+++ b/apache-shiro/src/main/resources/log4j.properties
@@ -0,0 +1,12 @@
+log4j.rootLogger=INFO, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.logger.org.apache=WARN
+
+log4j.logger.org.apache.shiro=INFO
+
+log4j.logger.org.apache.shiro.util.ThreadContext=WARN
+log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN
\ No newline at end of file
diff --git a/apache-shiro/src/main/resources/shiro.ini b/apache-shiro/src/main/resources/shiro.ini
new file mode 100644
index 0000000000..0bb7567d1e
--- /dev/null
+++ b/apache-shiro/src/main/resources/shiro.ini
@@ -0,0 +1,9 @@
+[users]
+user = password,admin
+user2 = password2,editor
+user3 = password3,author
+
+[roles]
+admin = *
+editor = articles:*
+author = articles:compose,articles:save
\ No newline at end of file
diff --git a/apache-velocity/src/main/webapp/WEB-INF/velocity.properties b/apache-velocity/src/main/webapp/WEB-INF/velocity.properties
index 00e0b7e410..97b19f4cb7 100644
--- a/apache-velocity/src/main/webapp/WEB-INF/velocity.properties
+++ b/apache-velocity/src/main/webapp/WEB-INF/velocity.properties
@@ -1,4 +1,4 @@
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
-webapp.resource.loader.path = .
+webapp.resource.loader.path =
webapp.resource.loader.cache = true
\ No newline at end of file
diff --git a/asciidoctor/README.md b/asciidoctor/README.md
index 164200d227..3c602b6abd 100644
--- a/asciidoctor/README.md
+++ b/asciidoctor/README.md
@@ -1,3 +1,4 @@
### Relevant articles
-- [Introduction to Asciidoctor](http://www.baeldung.com/introduction-to-asciidoctor)
\ No newline at end of file
+- [Introduction to Asciidoctor](http://www.baeldung.com/introduction-to-asciidoctor)
+- [Generating a Book with Asciidoctor](http://www.baeldung.com/asciidoctor-book)
diff --git a/bootique/config.yml b/bootique/config.yml
new file mode 100644
index 0000000000..269b4ab867
--- /dev/null
+++ b/bootique/config.yml
@@ -0,0 +1,11 @@
+log:
+ level: warn
+ appenders:
+ - type: file
+ logFormat: '%c{20}: %m%n'
+ file: /home/logger.log
+
+jetty:
+ context: /hello
+ connector:
+ port: 10001
diff --git a/bootique/dependency-reduced-pom.xml b/bootique/dependency-reduced-pom.xml
new file mode 100644
index 0000000000..ed18f4e42a
--- /dev/null
+++ b/bootique/dependency-reduced-pom.xml
@@ -0,0 +1,50 @@
+
+
+
+ bootique-parent
+ io.bootique.parent
+ 0.12
+
+ 4.0.0
+ com.baeldung.bootique
+ bootique
+ bootique
+ 1.0-SNAPSHOT
+ http://maven.apache.org
+
+
+
+ maven-shade-plugin
+
+
+
+
+
+ io.bootique
+ bootique-test
+ 0.23
+ test
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+
+
+
+
+ io.bootique.bom
+ bootique-bom
+ 0.23
+ pom
+ import
+
+
+
+
+ com.baeldung.bootique.App
+
+
+
diff --git a/bootique/pom.xml b/bootique/pom.xml
new file mode 100644
index 0000000000..28b716e104
--- /dev/null
+++ b/bootique/pom.xml
@@ -0,0 +1,66 @@
+
+ 4.0.0
+ com.baeldung.bootique
+ bootique
+ jar
+ 1.0-SNAPSHOT
+ bootique
+ http://maven.apache.org
+
+
+ com.baeldung.bootique.App
+
+
+
+ io.bootique.parent
+ bootique-parent
+ 0.12
+
+
+
+
+
+ io.bootique.bom
+ bootique-bom
+ 0.23
+ pom
+ import
+
+
+
+
+
+
+ io.bootique.jersey
+ bootique-jersey
+ compile
+
+
+ io.bootique.logback
+ bootique-logback
+ compile
+
+
+ io.bootique
+ bootique-test
+ test
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/bootique/src/main/java/com/baeldung/bootique/App.java b/bootique/src/main/java/com/baeldung/bootique/App.java
new file mode 100644
index 0000000000..cc1b90ce7d
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/App.java
@@ -0,0 +1,41 @@
+package com.baeldung.bootique;
+
+import com.baeldung.bootique.module.ModuleBinder;
+import com.baeldung.bootique.router.IndexController;
+import com.baeldung.bootique.router.SaveController;
+import com.google.inject.Module;
+import io.bootique.Bootique;
+import io.bootique.jersey.JerseyModule;
+import io.bootique.log.BootLogger;
+
+import java.util.function.Supplier;
+
+public class App {
+
+ public static void main(String[] args) {
+ Module module = binder -> JerseyModule.extend(binder).addResource(IndexController.class)
+ .addResource(SaveController.class);
+ Bootique.app(args).module(module).module(ModuleBinder.class).bootLogger(new BootLogger() {
+ @Override
+ public void trace(Supplier arg0) {
+ // ...
+ }
+
+ @Override
+ public void stdout(String arg0) {
+ // ...
+ }
+
+ @Override
+ public void stderr(String arg0, Throwable arg1) {
+ // ...
+ }
+
+ @Override
+ public void stderr(String arg0) {
+ // ...
+ }
+ }).autoLoadModules().exec();
+ }
+
+}
diff --git a/bootique/src/main/java/com/baeldung/bootique/module/ModuleBinder.java b/bootique/src/main/java/com/baeldung/bootique/module/ModuleBinder.java
new file mode 100644
index 0000000000..8811d48652
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/module/ModuleBinder.java
@@ -0,0 +1,15 @@
+package com.baeldung.bootique.module;
+
+import com.baeldung.bootique.service.HelloService;
+import com.baeldung.bootique.service.impl.HelloServiceImpl;
+import com.google.inject.Binder;
+import com.google.inject.Module;
+
+public class ModuleBinder implements Module {
+
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(HelloService.class).to(HelloServiceImpl.class);
+ }
+
+}
diff --git a/bootique/src/main/java/com/baeldung/bootique/module/ModuleProvider.java b/bootique/src/main/java/com/baeldung/bootique/module/ModuleProvider.java
new file mode 100644
index 0000000000..cf78177e6d
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/module/ModuleProvider.java
@@ -0,0 +1,13 @@
+package com.baeldung.bootique.module;
+
+import com.google.inject.Module;
+import io.bootique.BQModuleProvider;
+
+public class ModuleProvider implements BQModuleProvider {
+
+ @Override
+ public Module module() {
+ return new ModuleBinder();
+ }
+
+}
diff --git a/bootique/src/main/java/com/baeldung/bootique/router/IndexController.java b/bootique/src/main/java/com/baeldung/bootique/router/IndexController.java
new file mode 100644
index 0000000000..6e3b31df41
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/router/IndexController.java
@@ -0,0 +1,14 @@
+package com.baeldung.bootique.router;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+@Path("/")
+public class IndexController {
+
+ @GET
+ public String index() {
+ return "Hello, baeldung!";
+ }
+
+}
diff --git a/bootique/src/main/java/com/baeldung/bootique/router/SaveController.java b/bootique/src/main/java/com/baeldung/bootique/router/SaveController.java
new file mode 100644
index 0000000000..f38f59708c
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/router/SaveController.java
@@ -0,0 +1,20 @@
+package com.baeldung.bootique.router;
+
+import com.baeldung.bootique.service.HelloService;
+import com.google.inject.Inject;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+@Path("/save")
+public class SaveController {
+
+ @Inject
+ HelloService helloService;
+
+ @POST
+ public String save() {
+ return "Data Saved!";
+ }
+
+}
diff --git a/bootique/src/main/java/com/baeldung/bootique/service/HelloService.java b/bootique/src/main/java/com/baeldung/bootique/service/HelloService.java
new file mode 100644
index 0000000000..74c0401cc3
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/service/HelloService.java
@@ -0,0 +1,7 @@
+package com.baeldung.bootique.service;
+
+public interface HelloService {
+
+ boolean save();
+
+}
diff --git a/bootique/src/main/java/com/baeldung/bootique/service/impl/HelloServiceImpl.java b/bootique/src/main/java/com/baeldung/bootique/service/impl/HelloServiceImpl.java
new file mode 100644
index 0000000000..d2c0b5b838
--- /dev/null
+++ b/bootique/src/main/java/com/baeldung/bootique/service/impl/HelloServiceImpl.java
@@ -0,0 +1,12 @@
+package com.baeldung.bootique.service.impl;
+
+import com.baeldung.bootique.service.HelloService;
+
+public class HelloServiceImpl implements HelloService {
+
+ @Override
+ public boolean save() {
+ return true;
+ }
+
+}
diff --git a/bootique/src/main/resources/META-INF/services/io.bootique.BQModuleProvider b/bootique/src/main/resources/META-INF/services/io.bootique.BQModuleProvider
new file mode 100644
index 0000000000..714cf3a2df
--- /dev/null
+++ b/bootique/src/main/resources/META-INF/services/io.bootique.BQModuleProvider
@@ -0,0 +1 @@
+com.baeldung.bootique.module.ModuleProvider
\ No newline at end of file
diff --git a/bootique/src/test/java/com/baeldung/bootique/AppTest.java b/bootique/src/test/java/com/baeldung/bootique/AppTest.java
new file mode 100644
index 0000000000..8856780ed4
--- /dev/null
+++ b/bootique/src/test/java/com/baeldung/bootique/AppTest.java
@@ -0,0 +1,27 @@
+package com.baeldung.bootique;
+
+import com.baeldung.bootique.service.HelloService;
+import io.bootique.BQRuntime;
+import io.bootique.test.junit.BQDaemonTestFactory;
+import io.bootique.test.junit.BQTestFactory;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class AppTest {
+
+ @Rule
+ public BQTestFactory bqTestFactory = new BQTestFactory();
+
+ @Rule
+ public BQDaemonTestFactory bqDaemonTestFactory = new BQDaemonTestFactory();
+
+ @Test
+ public void givenService_expectBoolen() {
+ BQRuntime runtime = bqTestFactory.app("--server").autoLoadModules().createRuntime();
+ HelloService service = runtime.getInstance(HelloService.class);
+ assertEquals(true, service.save());
+ }
+
+}
diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java b/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java
index 299f74e877..5dc00dba25 100644
--- a/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java
+++ b/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java
@@ -6,7 +6,7 @@ public class ServiceMain {
public static void main(String[] args) throws InterruptedException {
ProcessHandle thisProcess = ProcessHandle.current();
- long pid = thisProcess.getPid();
+ long pid = thisProcess.pid();
Optional opArgs = Optional.ofNullable(args);
String procName = opArgs.map(str -> str.length > 0 ? str[0] : null).orElse(System.getProperty("sun.java.command"));
diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java
new file mode 100644
index 0000000000..93579019a1
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/language/Java9ObjectsAPIUnitTest.java
@@ -0,0 +1,86 @@
+package com.baeldung.java9.language;
+
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class Java9ObjectsAPIUnitTest {
+
+ private List aMethodReturningNullList(){
+ return null;
+ }
+
+ @Test
+ public void givenNullObject_whenRequireNonNullElse_thenElse(){
+ List aList = Objects.requireNonNullElse(
+ aMethodReturningNullList(), Collections.EMPTY_LIST);
+ assertThat(aList, is(Collections.EMPTY_LIST));
+ }
+
+ private List aMethodReturningNonNullList(){
+ return List.of("item1", "item2");
+ }
+
+ @Test
+ public void givenObject_whenRequireNonNullElse_thenObject(){
+ List aList = Objects.requireNonNullElse(
+ aMethodReturningNonNullList(), Collections.EMPTY_LIST);
+ assertThat(aList, is(List.of("item1", "item2")));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void givenNull_whenRequireNonNullElse_thenException(){
+ Objects.requireNonNullElse(null, null);
+ }
+
+ @Test
+ public void givenObject_whenRequireNonNullElseGet_thenObject(){
+ List aList = Objects.requireNonNullElseGet(null, List::of);
+ assertThat(aList, is(List.of()));
+ }
+
+ @Test
+ public void givenNumber_whenInvokeCheckIndex_thenNumber(){
+ int length = 5;
+ assertThat(Objects.checkIndex(4, length), is(4));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void givenOutOfRangeNumber_whenInvokeCheckIndex_thenException(){
+ int length = 5;
+ Objects.checkIndex(5, length);
+ }
+
+
+ @Test
+ public void givenSubRange_whenCheckFromToIndex_thenNumber(){
+ int length = 6;
+ assertThat(Objects.checkFromToIndex(2,length,length), is(2));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void givenInvalidSubRange_whenCheckFromToIndex_thenException(){
+ int length = 6;
+ Objects.checkFromToIndex(2,7,length);
+ }
+
+
+ @Test
+ public void givenSubRange_whenCheckFromIndexSize_thenNumber(){
+ int length = 6;
+ assertThat(Objects.checkFromIndexSize(2,3,length), is(2));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void givenInvalidSubRange_whenCheckFromIndexSize_thenException(){
+ int length = 6;
+ Objects.checkFromIndexSize(2, 6, length);
+ }
+
+
+}
diff --git a/core-java/hashcode/pom.xml b/core-java/hashcode/pom.xml
deleted file mode 100644
index 393aa69153..0000000000
--- a/core-java/hashcode/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
- 4.0.0
- com.baeldung.hashcode
- hashcode
- 1.0
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- 1.8
- 1.8
-
-
-
-
-
-
- junit
- junit
- 4.12
- test
-
-
- org.slf4j
- slf4j-api
- 1.7.25
-
-
- org.slf4j
- slf4j-simple
- 1.7.25
-
-
-
\ No newline at end of file
diff --git a/core-java/hashcode/src/main/java/com/baeldung/application/Application.java b/core-java/hashcode/src/main/java/com/baeldung/application/Application.java
deleted file mode 100644
index 08c670c82f..0000000000
--- a/core-java/hashcode/src/main/java/com/baeldung/application/Application.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.application;
-
-import com.baeldung.entities.User;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Application {
-
- public static void main(String[] args) {
- Map users = new HashMap<>();
- User user1 = new User(1L, "John", "john@domain.com");
- User user2 = new User(2L, "Jennifer", "jennifer@domain.com");
- User user3 = new User(3L, "Mary", "mary@domain.com");
-
- users.put(user1, user1);
- users.put(user2, user2);
- users.put(user3, user3);
-
- if (users.containsKey(user1)) {
- System.out.print("User found in the collection");
- }
- }
-}
diff --git a/core-java/hashcode/src/main/java/com/baeldung/entities/User.java b/core-java/hashcode/src/main/java/com/baeldung/entities/User.java
deleted file mode 100644
index a976233562..0000000000
--- a/core-java/hashcode/src/main/java/com/baeldung/entities/User.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.baeldung.entities;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class User {
-
- private final Logger logger = LoggerFactory.getLogger(User.class);
- private long id;
- private String name;
- private String email;
-
- public User(long id, String name, String email) {
- this.id = id;
- this.name = name;
- this.email = email;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null) return false;
- if (this.getClass() != o.getClass()) return false;
- User user = (User) o;
- return id != user.id && (!name.equals(user.name) && !email.equals(user.email));
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 31 * hash + (int) id;
- hash = 31 * hash + (name == null ? 0 : name.hashCode());
- hash = 31 * hash + (email == null ? 0 : email.hashCode());
- logger.info("hashCode() method called - Computed hash: " + hash);
- return hash;
- }
- // getters and setters here
-}
diff --git a/core-java/hashcode/src/test/java/com/baeldung/application/ApplicationTest.java b/core-java/hashcode/src/test/java/com/baeldung/application/ApplicationTest.java
deleted file mode 100644
index dcd853f451..0000000000
--- a/core-java/hashcode/src/test/java/com/baeldung/application/ApplicationTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.baeldung.application;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import static org.junit.Assert.assertEquals;
-
-public class ApplicationTest {
-
- private ByteArrayOutputStream outContent;
-
- @Before
- public void setUpPrintStreamInstance() throws Exception {
- this.outContent = new ByteArrayOutputStream();
- System.setOut(new PrintStream(outContent));
- }
-
- @After
- public void tearDownByteArrayOutputStream() throws Exception {
- outContent = null;
- }
-
- @Test
- public void main_NoInputState_TextPrintedToConsole() throws Exception {
- Application.main(new String[]{});
- assertEquals("User found in the collection", outContent.toString());
- }
-}
\ No newline at end of file
diff --git a/core-java/hashcode/src/test/java/com/baeldung/entities/UserTest.java b/core-java/hashcode/src/test/java/com/baeldung/entities/UserTest.java
deleted file mode 100644
index 01f6085d7e..0000000000
--- a/core-java/hashcode/src/test/java/com/baeldung/entities/UserTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.baeldung.entities;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class UserTest {
-
- private User user;
- private User comparisonUser;
-
- @Before
- public void setUpUserInstances() {
- this.user = new User(1L, "test", "test@domain.com");
- this.comparisonUser = this.user;
- }
-
- @After
- public void tearDownUserInstances() {
- user = null;
- comparisonUser = null;
- }
-
- @Test
- public void equals_EqualUserInstance_TrueAssertion(){
- Assert.assertTrue(user.equals(comparisonUser));
- }
-
- @Test
- public void hashCode_UserHash_TrueAssertion() {
- Assert.assertEquals(1792276941, user.hashCode());
- }
-}
\ No newline at end of file
diff --git a/core-java/pom.xml b/core-java/pom.xml
index 73b1c22ed8..422965a0ed 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -80,7 +80,11 @@
-
+
+ log4j
+ log4j
+ 1.2.17
+
org.slf4j
slf4j-api
diff --git a/core-java/src/main/java/com/baeldung/concurrent/cyclicbarrier/CyclicBarrierDemo.java b/core-java/src/main/java/com/baeldung/concurrent/cyclicbarrier/CyclicBarrierDemo.java
index 977dae4fdb..758bdecd0c 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/cyclicbarrier/CyclicBarrierDemo.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/cyclicbarrier/CyclicBarrierDemo.java
@@ -15,14 +15,12 @@ public class CyclicBarrierDemo {
private int NUM_PARTIAL_RESULTS;
private int NUM_WORKERS;
-
private void runSimulation(int numWorkers, int numberOfPartialResults) {
NUM_PARTIAL_RESULTS = numberOfPartialResults;
NUM_WORKERS = numWorkers;
cyclicBarrier = new CyclicBarrier(NUM_WORKERS, new AggregatorThread());
- System.out.println("Spawning " + NUM_WORKERS + " worker threads to compute "
- + NUM_PARTIAL_RESULTS + " partial results each");
+ System.out.println("Spawning " + NUM_WORKERS + " worker threads to compute " + NUM_PARTIAL_RESULTS + " partial results each");
for (int i = 0; i < NUM_WORKERS; i++) {
Thread worker = new Thread(new NumberCruncherThread());
worker.setName("Thread " + i);
@@ -38,8 +36,7 @@ public class CyclicBarrierDemo {
List partialResult = new ArrayList<>();
for (int i = 0; i < NUM_PARTIAL_RESULTS; i++) {
Integer num = random.nextInt(10);
- System.out.println(thisThreadName
- + ": Crunching some numbers! Final result - " + num);
+ System.out.println(thisThreadName + ": Crunching some numbers! Final result - " + num);
partialResult.add(num);
}
partialResults.add(partialResult);
@@ -57,13 +54,12 @@ public class CyclicBarrierDemo {
@Override
public void run() {
String thisThreadName = Thread.currentThread().getName();
- System.out.println(thisThreadName + ": Computing final sum of " + NUM_WORKERS
- + " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
+ System.out.println(thisThreadName + ": Computing final sum of " + NUM_WORKERS + " workers, having " + NUM_PARTIAL_RESULTS + " results each.");
int sum = 0;
for (List threadResult : partialResults) {
System.out.print("Adding ");
for (Integer partialResult : threadResult) {
- System.out.print(partialResult+" ");
+ System.out.print(partialResult + " ");
sum += partialResult;
}
System.out.println();
diff --git a/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java b/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java
index c5672706ad..4de420900a 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java
@@ -15,7 +15,8 @@ public class Philosopher implements Runnable {
Thread.sleep(((int) (Math.random() * 100)));
}
- @Override public void run() {
+ @Override
+ public void run() {
try {
while (true) {
doAction(System.nanoTime() + ": Thinking"); // thinking
diff --git a/core-java/src/main/java/com/baeldung/concurrent/executorservice/ExecutorServiceDemo.java b/core-java/src/main/java/com/baeldung/concurrent/executorservice/ExecutorServiceDemo.java
index ae2b279d9a..83a9fb6692 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/executorservice/ExecutorServiceDemo.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/executorservice/ExecutorServiceDemo.java
@@ -6,22 +6,22 @@ import java.util.concurrent.TimeUnit;
public class ExecutorServiceDemo {
- ExecutorService executor = Executors.newFixedThreadPool(10);
+ ExecutorService executor = Executors.newFixedThreadPool(10);
- public void execute() {
+ public void execute() {
- executor.submit(() -> {
- new Task();
- });
+ executor.submit(() -> {
+ new Task();
+ });
- executor.shutdown();
- executor.shutdownNow();
- try {
- executor.awaitTermination(20l, TimeUnit.NANOSECONDS);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
+ executor.shutdown();
+ executor.shutdownNow();
+ try {
+ executor.awaitTermination(20l, TimeUnit.NANOSECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
- }
+ }
}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/future/FutureDemo.java b/core-java/src/main/java/com/baeldung/concurrent/future/FutureDemo.java
index 7cb611be0f..4794d5cb61 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/future/FutureDemo.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/future/FutureDemo.java
@@ -9,36 +9,36 @@ import java.util.concurrent.TimeoutException;
public class FutureDemo {
- public String invoke() {
+ public String invoke() {
- String str = null;
+ String str = null;
- ExecutorService executorService = Executors.newFixedThreadPool(10);
+ ExecutorService executorService = Executors.newFixedThreadPool(10);
- Future future = executorService.submit(() -> {
- // Task
- Thread.sleep(10000l);
- return "Hellow world";
- });
+ Future future = executorService.submit(() -> {
+ // Task
+ Thread.sleep(10000l);
+ return "Hellow world";
+ });
- future.cancel(false);
+ future.cancel(false);
- try {
- future.get(20, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e1) {
- e1.printStackTrace();
- }
+ try {
+ future.get(20, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e1) {
+ e1.printStackTrace();
+ }
- if (future.isDone() && !future.isCancelled()) {
- try {
- str = future.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
+ if (future.isDone() && !future.isCancelled()) {
+ try {
+ str = future.get();
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
- return str;
+ return str;
- }
+ }
}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/threadfactory/BaeldungThreadFactory.java b/core-java/src/main/java/com/baeldung/concurrent/threadfactory/BaeldungThreadFactory.java
index 8744027e40..f708804cae 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/threadfactory/BaeldungThreadFactory.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/threadfactory/BaeldungThreadFactory.java
@@ -4,20 +4,20 @@ import java.util.concurrent.ThreadFactory;
public class BaeldungThreadFactory implements ThreadFactory {
- private int threadId;
- private String name;
+ private int threadId;
+ private String name;
- public BaeldungThreadFactory(String name) {
- threadId = 1;
- this.name = name;
- }
+ public BaeldungThreadFactory(String name) {
+ threadId = 1;
+ this.name = name;
+ }
- @Override
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r, name + "-Thread_" + threadId);
- System.out.println("created new thread with id : " + threadId + " and name : " + t.getName());
- threadId++;
- return t;
- }
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, name + "-Thread_" + threadId);
+ System.out.println("created new thread with id : " + threadId + " and name : " + t.getName());
+ threadId++;
+ return t;
+ }
}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/threadfactory/Task.java b/core-java/src/main/java/com/baeldung/concurrent/threadfactory/Task.java
index 04ba62d457..a69623c667 100644
--- a/core-java/src/main/java/com/baeldung/concurrent/threadfactory/Task.java
+++ b/core-java/src/main/java/com/baeldung/concurrent/threadfactory/Task.java
@@ -2,9 +2,9 @@ package com.baeldung.concurrent.threadfactory;
public class Task implements Runnable {
- @Override
- public void run() {
- // task details
- }
-
+ @Override
+ public void run() {
+ // task details
+ }
+
}
diff --git a/core-java/src/main/java/com/baeldung/concurrent/volatilekeyword/SharedObject.java b/core-java/src/main/java/com/baeldung/concurrent/volatilekeyword/SharedObject.java
new file mode 100644
index 0000000000..063c835481
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/concurrent/volatilekeyword/SharedObject.java
@@ -0,0 +1,13 @@
+package com.baeldung.concurrent.volatilekeyword;
+
+
+public class SharedObject {
+ private volatile int count=0;
+
+ void increamentCount(){
+ count++;
+ }
+ public int getCount(){
+ return count;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java
new file mode 100644
index 0000000000..0d69d0e7ec
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java
@@ -0,0 +1,13 @@
+package com.baeldung.designpatterns.adapter;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class AdapterPatternDriver {
+
+ public static void main(String args[]) {
+ LuxuryCarsSpeedAdapter luxuryCars = new LuxuryCarsSpeedAdapterImpl();
+ LOG.info("Bugatti Veyron Super Sport's top speed is " + luxuryCars.bugattiVeyronInKMPH() + " Kmph.");
+ LOG.info("McLaren F1 top speed is " + luxuryCars.mcLarenInKMPH() + " Kmph.");
+ LOG.info("Aston Martin One-77 top speed is " + luxuryCars.astonMartinInKMPH() + " Kmph.");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeed.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeed.java
new file mode 100644
index 0000000000..278329b994
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeed.java
@@ -0,0 +1,15 @@
+package com.baeldung.designpatterns.adapter;
+
+public class LuxuryCarsSpeed {
+ public double bugattiVeyronInMPH() {
+ return 268;
+ }
+
+ public double mcLarenInMPH() {
+ return 241;
+ }
+
+ public double astonMartinInMPH() {
+ return 220;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapter.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapter.java
new file mode 100644
index 0000000000..84f7be2729
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapter.java
@@ -0,0 +1,7 @@
+package com.baeldung.designpatterns.adapter;
+
+public interface LuxuryCarsSpeedAdapter {
+ public double bugattiVeyronInKMPH();
+ public double mcLarenInKMPH();
+ public double astonMartinInKMPH();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapterImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapterImpl.java
new file mode 100644
index 0000000000..2767b78e38
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapterImpl.java
@@ -0,0 +1,26 @@
+package com.baeldung.designpatterns.adapter;
+
+public class LuxuryCarsSpeedAdapterImpl extends LuxuryCarsSpeed implements LuxuryCarsSpeedAdapter {
+
+ @Override
+ public double bugattiVeyronInKMPH() {
+ double mph = super.bugattiVeyronInMPH();
+ return convertMPHtoKMPH(mph);
+ }
+
+ @Override
+ public double mcLarenInKMPH() {
+ double mph = super.mcLarenInMPH();
+ return convertMPHtoKMPH(mph);
+ }
+
+ @Override
+ public double astonMartinInKMPH() {
+ double mph = super.astonMartinInMPH();
+ return convertMPHtoKMPH(mph);
+ }
+
+ private double convertMPHtoKMPH(double mph) {
+ return mph * 1.60934;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java
new file mode 100644
index 0000000000..97a4a9508c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java
@@ -0,0 +1,12 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Blue implements Color {
+
+ @Override
+ public void fillColor() {
+ LOG.info("Color : Blue");
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java
new file mode 100644
index 0000000000..921deadcac
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java
@@ -0,0 +1,14 @@
+package com.baeldung.designpatterns.bridge;
+
+public class BridgePatternDriver {
+
+ public static void main(String[] args) {
+ //a square with red color
+ Shape square = new Square(new Red());
+ square.drawShape();
+
+ //a triangle with blue color
+ Shape triangle = new Triangle(new Blue());
+ triangle.drawShape();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java
new file mode 100644
index 0000000000..91d2b01609
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.bridge;
+
+public interface Color {
+ public void fillColor();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java
new file mode 100644
index 0000000000..8c22a94f00
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java
@@ -0,0 +1,12 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Red implements Color {
+
+ @Override
+ public void fillColor() {
+ LOG.info("Color : Red");
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java
new file mode 100644
index 0000000000..c4daf7a821
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java
@@ -0,0 +1,11 @@
+package com.baeldung.designpatterns.bridge;
+
+public abstract class Shape {
+ protected Color color;
+
+ public Shape(Color color) {
+ this.color = color;
+ }
+
+ abstract public void drawShape();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java
new file mode 100644
index 0000000000..6b377197eb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Square extends Shape {
+
+ public Square(Color color) {
+ super(color);
+ }
+
+ @Override
+ public void drawShape() {
+ LOG.info("Square drawn. ");
+ color.fillColor();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java
new file mode 100644
index 0000000000..900e78cf2b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Triangle extends Shape {
+
+ public Triangle(Color color) {
+ super(color);
+ }
+
+ @Override
+ public void drawShape() {
+ LOG.info("Triangle drawn. ");
+ color.fillColor();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java
new file mode 100644
index 0000000000..881add8b21
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.decorator;
+
+public class BubbleLights extends TreeDecorator {
+
+ public BubbleLights(ChristmasTree tree) {
+ super(tree);
+ }
+
+ public String decorate() {
+ return super.decorate() + decorateWithBubbleLights();
+ }
+
+ private String decorateWithBubbleLights() {
+ return " with Bubble Lights";
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java
new file mode 100644
index 0000000000..80a0865567
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.decorator;
+
+public interface ChristmasTree {
+ public String decorate();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java
new file mode 100644
index 0000000000..9241fd59db
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java
@@ -0,0 +1,10 @@
+package com.baeldung.designpatterns.decorator;
+
+public class ChristmasTreeImpl implements ChristmasTree {
+
+ @Override
+ public String decorate() {
+ return "Christmas tree";
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java
new file mode 100644
index 0000000000..f70991da6b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns.decorator;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class DecoratorPatternDriver {
+
+ public static void main(String[] args) {
+ //christmas tree with just one Garland
+ ChristmasTree tree1 = new Garland(new ChristmasTreeImpl());
+ LOG.info(tree1.decorate());
+
+ //christmas tree with two Garlands and one Bubble lights
+ ChristmasTree tree2 = new BubbleLights(new Garland(
+ new Garland(new ChristmasTreeImpl()))
+ );
+ LOG.info(tree2.decorate());
+
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java
new file mode 100644
index 0000000000..d2efd6e451
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.decorator;
+
+public class Garland extends TreeDecorator {
+
+ public Garland(ChristmasTree tree) {
+ super(tree);
+ }
+
+ public String decorate() {
+ return super.decorate() + decorateWithGarland();
+ }
+
+ private String decorateWithGarland() {
+ return " with Garland";
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java
new file mode 100644
index 0000000000..5427d2ac7e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java
@@ -0,0 +1,15 @@
+package com.baeldung.designpatterns.decorator;
+
+public abstract class TreeDecorator implements ChristmasTree {
+ private ChristmasTree tree;
+
+ public TreeDecorator(ChristmasTree tree) {
+ this.tree = tree;
+ }
+
+ @Override
+ public String decorate() {
+ return tree.decorate();
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java
new file mode 100644
index 0000000000..96a6bfb878
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.proxy;
+
+public interface ExpensiveObject {
+ public void process();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java
new file mode 100644
index 0000000000..7014d3811c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns.proxy;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;;
+
+public class ExpensiveObjectImpl implements ExpensiveObject {
+
+ public ExpensiveObjectImpl() {
+ heavyInitialConfiguration();
+ }
+
+ @Override
+ public void process() {
+ LOG.info("processing complete.");
+ }
+
+ private void heavyInitialConfiguration() {
+ LOG.info("Loading initial configuration...");
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java
new file mode 100644
index 0000000000..f36e688c90
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java
@@ -0,0 +1,13 @@
+package com.baeldung.designpatterns.proxy;
+
+public class ExpensiveObjectProxy implements ExpensiveObject{
+ private static ExpensiveObject object;
+
+ @Override
+ public void process() {
+ if(object == null) {
+ object = new ExpensiveObjectImpl();
+ }
+ object.process();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java
new file mode 100644
index 0000000000..088b069e28
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java
@@ -0,0 +1,9 @@
+package com.baeldung.designpatterns.proxy;
+
+public class ProxyPatternDriver {
+ public static void main(String[] args) {
+ ExpensiveObject object = new ExpensiveObjectProxy();
+ object.process();
+ object.process();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java b/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java
new file mode 100644
index 0000000000..0fc86e30a7
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java
@@ -0,0 +1,28 @@
+package com.baeldung.designpatterns.singleton;
+
+public class ClassSingleton {
+
+ private static ClassSingleton INSTANCE;
+ private String info = "Initial class info";
+
+ private ClassSingleton(){
+ }
+
+ public static ClassSingleton getInstance(){
+ if(INSTANCE == null){
+ INSTANCE = new ClassSingleton();
+ }
+
+ return INSTANCE;
+ }
+
+ // getters and setters
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java b/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java
new file mode 100644
index 0000000000..f75484477b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java
@@ -0,0 +1,26 @@
+package com.baeldung.designpatterns.singleton;
+
+public enum EnumSingleton {
+
+ INSTANCE("Initial enum info"); //Name of the single instance
+
+ private String info;
+
+ private EnumSingleton(String info) {
+ this.info = info;
+ }
+
+ public EnumSingleton getInstance(){
+ return INSTANCE;
+ }
+
+ //getters and setters
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java b/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java
new file mode 100644
index 0000000000..f8ca2ffa78
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java
@@ -0,0 +1,32 @@
+package com.baeldung.designpatterns.singleton;
+
+public class Sandbox {
+
+ public static void main(String[] args) {
+
+ //Class singleton
+
+ ClassSingleton classSingleton1 = ClassSingleton.getInstance();
+ //OurSingleton object1 = new OurSingleton(); // The constructor OurSingleton() is not visible
+
+ System.out.println(classSingleton1.getInfo()); //Initial class info
+
+ ClassSingleton classSingleton2 = ClassSingleton.getInstance();
+ classSingleton2.setInfo("New class info");
+
+ System.out.println(classSingleton1.getInfo()); //New class info
+ System.out.println(classSingleton2.getInfo()); //New class info
+
+ //Enum singleton
+
+ EnumSingleton enumSingleton1 = EnumSingleton.INSTANCE.getInstance();
+
+ System.out.println(enumSingleton1.getInfo()); //Initial enum info
+
+ EnumSingleton enumSingleton2 = EnumSingleton.INSTANCE.getInstance();
+ enumSingleton2.setInfo("New enum info");
+
+ System.out.println(enumSingleton1.getInfo()); //New enum info
+ System.out.println(enumSingleton2.getInfo()); //New enum info
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java b/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java
new file mode 100644
index 0000000000..f7b6e4f3e9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java
@@ -0,0 +1,35 @@
+package com.baeldung.designpatterns.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+public class LogerUtil {
+
+ public final static Logger LOG = Logger.getLogger("GLOBAL");
+
+ static {
+ configuration();
+ }
+
+ private static void configuration() {
+ Properties props = new Properties();
+ try {
+ props.load(
+ new BufferedReader(
+ new InputStreamReader(
+ LogerUtil.class.getResourceAsStream("/log4jstructuraldp.properties")
+ )
+ )
+ );
+ } catch (IOException e) {
+ System.out.println("log4jstructuraldp.properties file not configured properly");
+ System.exit(0);
+ }
+ PropertyConfigurator.configure(props);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java b/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java
index 4afce56e39..7e6bb5d3b2 100644
--- a/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java
+++ b/core-java/src/main/java/com/baeldung/filesystem/jndi/LookupFSJNDI.java
@@ -14,26 +14,25 @@ public class LookupFSJNDI {
super();
init();
}
-
+
private void init() throws NamingException {
Hashtable env = new Hashtable();
-
- env.put (Context.INITIAL_CONTEXT_FACTORY,
- "com.sun.jndi.fscontext.RefFSContextFactory");
+
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
// URI to namespace (actual directory)
env.put(Context.PROVIDER_URL, "file:./src/test/resources");
-
+
ctx = new InitialContext(env);
}
public InitialContext getCtx() {
return ctx;
}
-
+
public File getFile(String fileName) {
File file;
try {
- file = (File)getCtx().lookup(fileName);
+ file = (File) getCtx().lookup(fileName);
} catch (NamingException e) {
file = null;
}
diff --git a/core-java/src/main/java/com/baeldung/hashcode/application/Application.java b/core-java/src/main/java/com/baeldung/hashcode/application/Application.java
deleted file mode 100644
index 08c670c82f..0000000000
--- a/core-java/src/main/java/com/baeldung/hashcode/application/Application.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.application;
-
-import com.baeldung.entities.User;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Application {
-
- public static void main(String[] args) {
- Map users = new HashMap<>();
- User user1 = new User(1L, "John", "john@domain.com");
- User user2 = new User(2L, "Jennifer", "jennifer@domain.com");
- User user3 = new User(3L, "Mary", "mary@domain.com");
-
- users.put(user1, user1);
- users.put(user2, user2);
- users.put(user3, user3);
-
- if (users.containsKey(user1)) {
- System.out.print("User found in the collection");
- }
- }
-}
diff --git a/core-java/src/main/java/com/baeldung/hashcode/entities/User.java b/core-java/src/main/java/com/baeldung/hashcode/entities/User.java
index a976233562..c46c3de65a 100644
--- a/core-java/src/main/java/com/baeldung/hashcode/entities/User.java
+++ b/core-java/src/main/java/com/baeldung/hashcode/entities/User.java
@@ -1,4 +1,4 @@
-package com.baeldung.entities;
+package com.baeldung.hashcode.entities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -18,13 +18,16 @@ public class User {
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null) return false;
- if (this.getClass() != o.getClass()) return false;
+ if (this == o)
+ return true;
+ if (o == null)
+ return false;
+ if (this.getClass() != o.getClass())
+ return false;
User user = (User) o;
return id != user.id && (!name.equals(user.name) && !email.equals(user.email));
}
-
+
@Override
public int hashCode() {
int hash = 7;
diff --git a/core-java/src/main/java/com/baeldung/jmx/JMXTutorialMainlauncher.java b/core-java/src/main/java/com/baeldung/jmx/JMXTutorialMainlauncher.java
index 220b9a8ec6..21044f82c4 100644
--- a/core-java/src/main/java/com/baeldung/jmx/JMXTutorialMainlauncher.java
+++ b/core-java/src/main/java/com/baeldung/jmx/JMXTutorialMainlauncher.java
@@ -10,7 +10,6 @@ public class JMXTutorialMainlauncher {
private static final Logger LOG = LoggerFactory.getLogger(JMXTutorialMainlauncher.class);
-
public static void main(String[] args) {
// TODO Auto-generated method stub
diff --git a/core-java/src/main/java/com/baeldung/java/networking/README.md b/core-java/src/main/java/com/baeldung/networking/README.md
similarity index 100%
rename from core-java/src/main/java/com/baeldung/java/networking/README.md
rename to core-java/src/main/java/com/baeldung/networking/README.md
diff --git a/core-java/src/main/java/com/baeldung/java/networking/cookies/PersistentCookieStore.java b/core-java/src/main/java/com/baeldung/networking/cookies/PersistentCookieStore.java
similarity index 96%
rename from core-java/src/main/java/com/baeldung/java/networking/cookies/PersistentCookieStore.java
rename to core-java/src/main/java/com/baeldung/networking/cookies/PersistentCookieStore.java
index 0d66406ac2..5d30491cfe 100644
--- a/core-java/src/main/java/com/baeldung/java/networking/cookies/PersistentCookieStore.java
+++ b/core-java/src/main/java/com/baeldung/networking/cookies/PersistentCookieStore.java
@@ -1,4 +1,4 @@
-package com.baeldung.java.networking.cookies;
+package com.baeldung.networking.cookies;
import java.net.*;
import java.util.List;
diff --git a/core-java/src/main/java/com/baeldung/java/networking/cookies/ProxyAcceptCookiePolicy.java b/core-java/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java
similarity index 93%
rename from core-java/src/main/java/com/baeldung/java/networking/cookies/ProxyAcceptCookiePolicy.java
rename to core-java/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java
index 6d6371bfe0..0b5f6d7714 100644
--- a/core-java/src/main/java/com/baeldung/java/networking/cookies/ProxyAcceptCookiePolicy.java
+++ b/core-java/src/main/java/com/baeldung/networking/cookies/ProxyAcceptCookiePolicy.java
@@ -1,4 +1,4 @@
-package com.baeldung.java.networking.cookies;
+package com.baeldung.networking.cookies;
import java.net.*;
diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/EchoClient.java b/core-java/src/main/java/com/baeldung/networking/udp/EchoClient.java
similarity index 96%
rename from core-java/src/main/java/com/baeldung/java/networking/udp/EchoClient.java
rename to core-java/src/main/java/com/baeldung/networking/udp/EchoClient.java
index 916442533b..35a083de26 100644
--- a/core-java/src/main/java/com/baeldung/java/networking/udp/EchoClient.java
+++ b/core-java/src/main/java/com/baeldung/networking/udp/EchoClient.java
@@ -1,4 +1,4 @@
-package com.baeldung.java.networking.udp;
+package com.baeldung.networking.udp;
import java.io.IOException;
import java.net.DatagramPacket;
diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/EchoServer.java b/core-java/src/main/java/com/baeldung/networking/udp/EchoServer.java
similarity index 96%
rename from core-java/src/main/java/com/baeldung/java/networking/udp/EchoServer.java
rename to core-java/src/main/java/com/baeldung/networking/udp/EchoServer.java
index 900d330786..34f2971cc4 100644
--- a/core-java/src/main/java/com/baeldung/java/networking/udp/EchoServer.java
+++ b/core-java/src/main/java/com/baeldung/networking/udp/EchoServer.java
@@ -1,4 +1,4 @@
-package com.baeldung.java.networking.udp;
+package com.baeldung.networking.udp;
import java.io.IOException;
import java.net.DatagramPacket;
diff --git a/core-java/src/main/java/com/baeldung/networking/udp/broadcast/BroadcastingClient.java b/core-java/src/main/java/com/baeldung/networking/udp/broadcast/BroadcastingClient.java
new file mode 100644
index 0000000000..09794c2596
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/networking/udp/broadcast/BroadcastingClient.java
@@ -0,0 +1,85 @@
+package com.baeldung.networking.udp.broadcast;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class BroadcastingClient {
+ private DatagramSocket socket;
+ private InetAddress address;
+ private int expectedServerCount;
+ private byte[] buf;
+
+ public BroadcastingClient(int expectedServerCount) throws Exception {
+ this.expectedServerCount = expectedServerCount;
+ this.address = InetAddress.getByName("255.255.255.255");
+ }
+
+ public int discoverServers(String msg) throws IOException {
+ initializeSocketForBroadcasting();
+ copyMessageOnBuffer(msg);
+
+ // When we want to broadcast not just to local network, call listAllBroadcastAddresses() and execute broadcastPacket for each value.
+ broadcastPacket(address);
+
+ return receivePackets();
+ }
+
+ List listAllBroadcastAddresses() throws SocketException {
+ List broadcastList = new ArrayList<>();
+ Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface networkInterface = interfaces.nextElement();
+
+ if (networkInterface.isLoopback() || !networkInterface.isUp()) {
+ continue;
+ }
+
+ broadcastList.addAll(networkInterface.getInterfaceAddresses()
+ .stream()
+ .filter(address -> address.getBroadcast() != null)
+ .map(address -> address.getBroadcast())
+ .collect(Collectors.toList()));
+ }
+ return broadcastList;
+ }
+
+ private void initializeSocketForBroadcasting() throws SocketException {
+ socket = new DatagramSocket();
+ socket.setBroadcast(true);
+ }
+
+ private void copyMessageOnBuffer(String msg) {
+ buf = msg.getBytes();
+ }
+
+ private void broadcastPacket(InetAddress address) throws IOException {
+ DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445);
+ socket.send(packet);
+ }
+
+ private int receivePackets() throws IOException {
+ int serversDiscovered = 0;
+ while (serversDiscovered != expectedServerCount) {
+ receivePacket();
+ serversDiscovered++;
+ }
+ return serversDiscovered;
+ }
+
+ private void receivePacket() throws IOException {
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ socket.receive(packet);
+ }
+
+ public void close() {
+ socket.close();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/networking/udp/broadcast/BroadcastingEchoServer.java b/core-java/src/main/java/com/baeldung/networking/udp/broadcast/BroadcastingEchoServer.java
new file mode 100644
index 0000000000..b519f899bb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/networking/udp/broadcast/BroadcastingEchoServer.java
@@ -0,0 +1,44 @@
+package com.baeldung.networking.udp.broadcast;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+public class BroadcastingEchoServer extends Thread {
+
+ protected DatagramSocket socket = null;
+ protected boolean running;
+ protected byte[] buf = new byte[256];
+
+ public BroadcastingEchoServer() throws IOException {
+ socket = new DatagramSocket(null);
+ socket.setReuseAddress(true);
+ socket.bind(new InetSocketAddress(4445));
+ }
+
+ public void run() {
+ running = true;
+
+ while (running) {
+ try {
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ socket.receive(packet);
+ InetAddress address = packet.getAddress();
+ int port = packet.getPort();
+ packet = new DatagramPacket(buf, buf.length, address, port);
+ String received = new String(packet.getData(), 0, packet.getLength());
+ if (received.equals("end")) {
+ running = false;
+ continue;
+ }
+ socket.send(packet);
+ } catch (IOException e) {
+ e.printStackTrace();
+ running = false;
+ }
+ }
+ socket.close();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/networking/udp/multicast/MulticastEchoServer.java b/core-java/src/main/java/com/baeldung/networking/udp/multicast/MulticastEchoServer.java
new file mode 100644
index 0000000000..9d63dd6386
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/networking/udp/multicast/MulticastEchoServer.java
@@ -0,0 +1,41 @@
+package com.baeldung.networking.udp.multicast;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+
+public class MulticastEchoServer extends Thread {
+
+ protected MulticastSocket socket = null;
+ protected byte[] buf = new byte[256];
+ protected InetAddress group = null;
+
+ public MulticastEchoServer() throws IOException {
+ socket = new MulticastSocket(4446);
+ socket.setReuseAddress(true);
+ group = InetAddress.getByName("230.0.0.0");
+ socket.joinGroup(group);
+ }
+
+ public void run() {
+ try {
+ while (true) {
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ socket.receive(packet);
+ InetAddress address = packet.getAddress();
+ int port = packet.getPort();
+ packet = new DatagramPacket(buf, buf.length, address, port);
+ String received = new String(packet.getData(), 0, packet.getLength());
+ if (received.equals("end")) {
+ break;
+ }
+ socket.send(packet);
+ }
+ socket.leaveGroup(group);
+ socket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/networking/udp/multicast/MulticastingClient.java b/core-java/src/main/java/com/baeldung/networking/udp/multicast/MulticastingClient.java
new file mode 100644
index 0000000000..e89abc939d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/networking/udp/multicast/MulticastingClient.java
@@ -0,0 +1,53 @@
+package com.baeldung.networking.udp.multicast;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+
+public class MulticastingClient {
+ private DatagramSocket socket;
+ private InetAddress group;
+ private int expectedServerCount;
+ private byte[] buf;
+
+ public MulticastingClient(int expectedServerCount) throws Exception {
+ this.expectedServerCount = expectedServerCount;
+ this.socket = new DatagramSocket();
+ this.group = InetAddress.getByName("230.0.0.0");
+ }
+
+ public int discoverServers(String msg) throws IOException {
+ copyMessageOnBuffer(msg);
+ multicastPacket();
+
+ return receivePackets();
+ }
+
+ private void copyMessageOnBuffer(String msg) {
+ buf = msg.getBytes();
+ }
+
+ private void multicastPacket() throws IOException {
+ DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 4446);
+ socket.send(packet);
+ }
+
+ private int receivePackets() throws IOException {
+ int serversDiscovered = 0;
+ while (serversDiscovered != expectedServerCount) {
+ receivePacket();
+ serversDiscovered++;
+ }
+ return serversDiscovered;
+ }
+
+ private void receivePacket() throws IOException {
+ DatagramPacket packet = new DatagramPacket(buf, buf.length);
+ socket.receive(packet);
+ }
+
+ public void close() {
+ socket.close();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/socket/EchoClient.java b/core-java/src/main/java/com/baeldung/socket/EchoClient.java
index cf5c253276..fa3901d5da 100644
--- a/core-java/src/main/java/com/baeldung/socket/EchoClient.java
+++ b/core-java/src/main/java/com/baeldung/socket/EchoClient.java
@@ -8,9 +8,8 @@ import java.net.*;
public class EchoClient {
-
private static final Logger LOG = LoggerFactory.getLogger(EchoClient.class);
-
+
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
diff --git a/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java b/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java
index ae00fc7cb4..d79a7c3ecb 100644
--- a/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java
+++ b/core-java/src/main/java/com/baeldung/stream/InfiniteStreams.java
@@ -1,6 +1,5 @@
package com.baeldung.stream;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/core-java/src/main/java/com/baeldung/string/StringHelper.java b/core-java/src/main/java/com/baeldung/string/StringHelper.java
index dac0d1272e..a9cc71d36a 100644
--- a/core-java/src/main/java/com/baeldung/string/StringHelper.java
+++ b/core-java/src/main/java/com/baeldung/string/StringHelper.java
@@ -12,15 +12,10 @@ class StringHelper {
}
static String removeLastCharOptional(String s) {
- return Optional.ofNullable(s)
- .filter(str -> str.length() != 0)
- .map(str -> str.substring(0, str.length() - 1))
- .orElse(s);
+ return Optional.ofNullable(s).filter(str -> str.length() != 0).map(str -> str.substring(0, str.length() - 1)).orElse(s);
}
static String removeLastCharRegexOptional(String s) {
- return Optional.ofNullable(s)
- .map(str -> str.replaceAll(".$", ""))
- .orElse(s);
+ return Optional.ofNullable(s).map(str -> str.replaceAll(".$", "")).orElse(s);
}
}
diff --git a/core-java/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java b/core-java/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java
index 130218acc2..21164a976c 100644
--- a/core-java/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java
+++ b/core-java/src/main/java/com/baeldung/stringtokenizer/MyTokenizer.java
@@ -25,11 +25,7 @@ public class MyTokenizer {
}
public List getTokensWithCollection(String str) {
- return Collections
- .list(new StringTokenizer(str, ","))
- .stream()
- .map(token -> (String) token)
- .collect(Collectors.toList());
+ return Collections.list(new StringTokenizer(str, ",")).stream().map(token -> (String) token).collect(Collectors.toList());
}
public List getTokensFromFile(String path, String delim) {
diff --git a/core-java/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java b/core-java/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java
index bfb6681f7c..5631616ea8 100644
--- a/core-java/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java
+++ b/core-java/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java
@@ -11,12 +11,12 @@ public class CustomTemporalAdjuster implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
switch (DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK))) {
- case FRIDAY:
- return temporal.plus(3, ChronoUnit.DAYS);
- case SATURDAY:
- return temporal.plus(2, ChronoUnit.DAYS);
- default:
- return temporal.plus(1, ChronoUnit.DAYS);
+ case FRIDAY:
+ return temporal.plus(3, ChronoUnit.DAYS);
+ case SATURDAY:
+ return temporal.plus(2, ChronoUnit.DAYS);
+ default:
+ return temporal.plus(1, ChronoUnit.DAYS);
}
}
}
diff --git a/core-java/src/main/java/com/baeldung/transferqueue/Consumer.java b/core-java/src/main/java/com/baeldung/transferqueue/Consumer.java
index 69d7ff2390..a5f70d9df5 100644
--- a/core-java/src/main/java/com/baeldung/transferqueue/Consumer.java
+++ b/core-java/src/main/java/com/baeldung/transferqueue/Consumer.java
@@ -9,7 +9,6 @@ import java.util.concurrent.atomic.AtomicInteger;
public class Consumer implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(Consumer.class);
-
private final TransferQueue transferQueue;
private final String name;
private final int numberOfMessagesToConsume;
diff --git a/core-java/src/main/resources/log4jstructuraldp.properties b/core-java/src/main/resources/log4jstructuraldp.properties
new file mode 100644
index 0000000000..5bc2bfe4b9
--- /dev/null
+++ b/core-java/src/main/resources/log4jstructuraldp.properties
@@ -0,0 +1,9 @@
+
+# Root logger
+log4j.rootLogger=INFO, file, stdout
+
+# Write to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/concurrent/accumulator/LongAccumulatorUnitTest.java b/core-java/src/test/java/com/baeldung/concurrent/accumulator/LongAccumulatorUnitTest.java
index 2f1abef64e..8cddf31245 100644
--- a/core-java/src/test/java/com/baeldung/concurrent/accumulator/LongAccumulatorUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/concurrent/accumulator/LongAccumulatorUnitTest.java
@@ -15,28 +15,24 @@ public class LongAccumulatorUnitTest {
@Test
public void givenLongAccumulator_whenApplyActionOnItFromMultipleThrads_thenShouldProduceProperResult() throws InterruptedException {
- //given
+ // given
ExecutorService executorService = Executors.newFixedThreadPool(8);
LongBinaryOperator sum = Long::sum;
LongAccumulator accumulator = new LongAccumulator(sum, 0L);
int numberOfThreads = 4;
int numberOfIncrements = 100;
- //when
- Runnable accumulateAction = () -> IntStream
- .rangeClosed(0, numberOfIncrements)
- .forEach(accumulator::accumulate);
+ // when
+ Runnable accumulateAction = () -> IntStream.rangeClosed(0, numberOfIncrements).forEach(accumulator::accumulate);
for (int i = 0; i < numberOfThreads; i++) {
executorService.execute(accumulateAction);
}
-
- //then
+ // then
executorService.awaitTermination(500, TimeUnit.MILLISECONDS);
executorService.shutdown();
assertEquals(accumulator.get(), 20200);
-
}
}
diff --git a/core-java/src/test/java/com/baeldung/concurrent/volatilekeyword/SharedObjectManualTest.java b/core-java/src/test/java/com/baeldung/concurrent/volatilekeyword/SharedObjectManualTest.java
new file mode 100644
index 0000000000..8770cb4e90
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/concurrent/volatilekeyword/SharedObjectManualTest.java
@@ -0,0 +1,71 @@
+package com.baeldung.concurrent.volatilekeyword;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+
+public class SharedObjectManualTest {
+
+ private SharedObject sharedObject;
+ private int valueReadByThread2;
+ private int valueReadByThread3;
+
+ @Before
+ public void setUp() {
+ sharedObject = new SharedObject();
+ }
+
+ @Test
+ public void whenOneThreadWrites_thenVolatileReadsFromMainMemory() throws InterruptedException {
+ Thread writer = new Thread(() -> sharedObject.increamentCount());
+ writer.start();
+
+
+ Thread readerOne = new Thread(() -> {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ valueReadByThread2 = sharedObject.getCount();
+ });
+ readerOne.start();
+
+ Thread readerTwo = new Thread(() -> {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ valueReadByThread3 = sharedObject.getCount();
+ });
+ readerTwo.start();
+
+ assertEquals(1, valueReadByThread2);
+ assertEquals(1, valueReadByThread3);
+
+ }
+
+ @Test
+ public void whenTwoThreadWrites_thenVolatileReadsFromMainMemory() throws InterruptedException {
+ Thread writerOne = new Thread(() -> sharedObject.increamentCount());
+ writerOne.start();
+ Thread.sleep(100);
+
+ Thread writerTwo = new Thread(() -> sharedObject.increamentCount());
+ writerTwo.start();
+ Thread.sleep(100);
+
+ Thread readerOne = new Thread(() -> valueReadByThread2 = sharedObject.getCount());
+ readerOne.start();
+
+ Thread readerTwo = new Thread(() -> valueReadByThread3 = sharedObject.getCount());
+ readerTwo.start();
+
+ assertEquals(2, valueReadByThread2);
+ assertEquals(2, valueReadByThread3);
+
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java
new file mode 100644
index 0000000000..fb483a8a68
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns;
+
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import com.baeldung.designpatterns.adapter.LuxuryCarsSpeedAdapter;
+import com.baeldung.designpatterns.adapter.LuxuryCarsSpeedAdapterImpl;
+
+public class AdapterPatternIntegrationTest {
+ @Test
+ public void givenLuxuryCarsAdapter_WhenConvertingMPHToKMPH_thenSuccessfullyConverted() {
+ LuxuryCarsSpeedAdapter luxuryCars = new LuxuryCarsSpeedAdapterImpl();
+ assertEquals(luxuryCars.bugattiVeyronInKMPH(), 431.30312, 0.00001);
+ assertEquals(luxuryCars.mcLarenInKMPH(), 387.85094, 0.00001);
+ assertEquals(luxuryCars.astonMartinInKMPH(), 354.0548, 0.00001);
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java
new file mode 100644
index 0000000000..56a7a704f2
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java
@@ -0,0 +1,52 @@
+package com.baeldung.designpatterns;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.designpatterns.bridge.Blue;
+import com.baeldung.designpatterns.bridge.Red;
+import com.baeldung.designpatterns.bridge.Shape;
+import com.baeldung.designpatterns.bridge.Square;
+import com.baeldung.designpatterns.bridge.Triangle;
+
+public class BridgePatternIntegrationTest {
+ public static TestAppenderDP appender;
+
+ @Before
+ public void setUp() {
+ appender = new TestAppenderDP();
+ LOG.addAppender(appender);
+ }
+
+ @Test
+ public void whenBridgePatternInvoked_thenConfigSuccess() {
+ //a square with red color
+ Shape square = new Square(new Red());
+ square.drawShape();
+
+ //a triangle with blue color
+ Shape triangle = new Triangle(new Blue());
+ triangle.drawShape();
+
+ final List log = appender.getLog();
+
+ assertThat((String) log.get(0).getMessage(), is("Square drawn. "));
+ assertThat((String) log.get(1).getMessage(), is("Color : Red"));
+ assertThat((String) log.get(2).getMessage(), is("Triangle drawn. "));
+ assertThat((String) log.get(3).getMessage(), is("Color : Blue"));
+ }
+
+ @After
+ public void tearDown() {
+ LOG.removeAppender(appender);
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java
new file mode 100644
index 0000000000..b3b3f988f1
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.designpatterns;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.baeldung.designpatterns.decorator.BubbleLights;
+import com.baeldung.designpatterns.decorator.ChristmasTree;
+import com.baeldung.designpatterns.decorator.ChristmasTreeImpl;
+import com.baeldung.designpatterns.decorator.Garland;
+
+public class DecoratorPatternIntegrationTest {
+ private ChristmasTree tree;
+
+ @Test
+ public void givenDecoratorPattern_WhenDecoratorsInjectedAtRuntime_thenConfigSuccess() {
+ //christmas tree with just one Garland
+ tree = new Garland(new ChristmasTreeImpl());
+ assertEquals(tree.decorate(), "Christmas tree with Garland");
+
+ //christmas tree with two Garlands and one Bubble lights
+ tree = new BubbleLights(new Garland(
+ new Garland(new ChristmasTreeImpl()))
+ );
+ assertEquals(tree.decorate(), "Christmas tree with Garland with Garland with Bubble Lights");
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java
new file mode 100644
index 0000000000..7fa95b31d7
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.designpatterns;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.designpatterns.proxy.ExpensiveObject;
+import com.baeldung.designpatterns.proxy.ExpensiveObjectProxy;
+
+public class ProxyPatternIntegrationTest {
+ public static TestAppenderDP appender;
+
+ @Before
+ public void setUp() {
+ appender = new TestAppenderDP();
+ LOG.addAppender(appender);
+ }
+
+ @Test
+ public void givenExpensiveObjectProxy_WhenObjectInitialized_thenInitializedOnlyOnce() {
+ ExpensiveObject object = new ExpensiveObjectProxy();
+ object.process();
+ object.process();
+
+ final List log = appender.getLog();
+
+ assertThat((String) log.get(0).getMessage(), is("Loading initial configuration..."));
+ assertThat((String) log.get(1).getMessage(), is("processing complete."));
+ assertThat((String) log.get(2).getMessage(), is("processing complete."));
+ }
+
+ @After
+ public void tearDown() {
+ LOG.removeAppender(appender);
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java b/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java
new file mode 100644
index 0000000000..613c26fa13
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java
@@ -0,0 +1,29 @@
+package com.baeldung.designpatterns;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.spi.LoggingEvent;
+
+public class TestAppenderDP extends AppenderSkeleton {
+ private final List log = new ArrayList();
+
+ @Override
+ public boolean requiresLayout() {
+ return false;
+ }
+
+ @Override
+ protected void append(final LoggingEvent loggingEvent) {
+ log.add(loggingEvent);
+ }
+
+ @Override
+ public void close() {
+ }
+
+ public List getLog() {
+ return new ArrayList(log);
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/hashcode/application/ApplicationTest.java b/core-java/src/test/java/com/baeldung/hashcode/application/ApplicationTest.java
index dcd853f451..60950fae7a 100644
--- a/core-java/src/test/java/com/baeldung/hashcode/application/ApplicationTest.java
+++ b/core-java/src/test/java/com/baeldung/hashcode/application/ApplicationTest.java
@@ -1,30 +1,26 @@
-package com.baeldung.application;
+package com.baeldung.hashcode.application;
-import org.junit.After;
-import org.junit.Before;
+import com.baeldung.hashcode.entities.User;
import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import static org.junit.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertTrue;
public class ApplicationTest {
- private ByteArrayOutputStream outContent;
-
- @Before
- public void setUpPrintStreamInstance() throws Exception {
- this.outContent = new ByteArrayOutputStream();
- System.setOut(new PrintStream(outContent));
- }
-
- @After
- public void tearDownByteArrayOutputStream() throws Exception {
- outContent = null;
- }
-
@Test
public void main_NoInputState_TextPrintedToConsole() throws Exception {
- Application.main(new String[]{});
- assertEquals("User found in the collection", outContent.toString());
+ Map users = new HashMap<>();
+ User user1 = new User(1L, "John", "john@domain.com");
+ User user2 = new User(2L, "Jennifer", "jennifer@domain.com");
+ User user3 = new User(3L, "Mary", "mary@domain.com");
+
+ users.put(user1, user1);
+ users.put(user2, user2);
+ users.put(user3, user3);
+
+ assertTrue(users.containsKey(user1));
}
}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/hashcode/entities/UserTest.java b/core-java/src/test/java/com/baeldung/hashcode/entities/UserTest.java
index 01f6085d7e..e356b4beef 100644
--- a/core-java/src/test/java/com/baeldung/hashcode/entities/UserTest.java
+++ b/core-java/src/test/java/com/baeldung/hashcode/entities/UserTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.entities;
+package com.baeldung.hashcode.entities;
import org.junit.After;
import org.junit.Assert;
@@ -23,7 +23,7 @@ public class UserTest {
}
@Test
- public void equals_EqualUserInstance_TrueAssertion(){
+ public void equals_EqualUserInstance_TrueAssertion() {
Assert.assertTrue(user.equals(comparisonUser));
}
diff --git a/core-java/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java b/core-java/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java
index 0fd6f7dfe8..fe10266043 100644
--- a/core-java/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/java8/lambda/exceptions/LambdaExceptionWrappersUnitTest.java
@@ -15,7 +15,6 @@ public class LambdaExceptionWrappersUnitTest {
private static final Logger LOG = LoggerFactory.getLogger(LambdaExceptionWrappersUnitTest.class);
-
private List integers;
@Before
diff --git a/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java b/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java
new file mode 100644
index 0000000000..ed36951f73
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java
@@ -0,0 +1,78 @@
+package com.baeldung.javanetworking.uriurl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import org.apache.commons.io.IOUtils;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class URIvsURLUnitTest {
+
+ @Test
+ public void whenCreatingURIs_thenSameInfo() throws URISyntaxException {
+ URI firstURI = new URI("somescheme://theuser:thepassword@someauthority:80/some/path?thequery#somefragment");
+ URI secondURI = new URI("somescheme", "theuser:thepassword", "someuthority", 80, "/some/path", "thequery", "somefragment");
+
+ assertEquals(firstURI.getScheme(), secondURI.getScheme());
+ assertEquals(firstURI.getPath(), secondURI.getPath());
+ }
+
+ @Test
+ public void whenCreatingURLs_thenSameInfo() throws MalformedURLException {
+ URL firstURL = new URL("http://theuser:thepassword@somehost:80/path/to/file?thequery#somefragment");
+ URL secondURL = new URL("http", "somehost", 80, "/path/to/file");
+
+ assertEquals(firstURL.getHost(), secondURL.getHost());
+ assertEquals(firstURL.getPath(), secondURL.getPath());
+ }
+
+ @Test
+ public void whenCreatingURI_thenCorrect() {
+ URI uri = URI.create("urn:isbn:1234567890");
+
+ assertNotNull(uri);
+ }
+
+ @Test(expected = MalformedURLException.class)
+ public void whenCreatingURLs_thenException() throws MalformedURLException {
+ URL theURL = new URL("otherprotocol://somehost/path/to/file");
+
+ assertNotNull(theURL);
+ }
+
+ @Test
+ public void givenObjects_whenConverting_thenCorrect() throws MalformedURLException, URISyntaxException {
+ String aURIString = "http://somehost:80/path?thequery";
+ URI uri = new URI(aURIString);
+ URL url = new URL(aURIString);
+
+ URL toURL = uri.toURL();
+ URI toURI = url.toURI();
+
+ assertNotNull(url);
+ assertNotNull(uri);
+ assertEquals(toURL.toString(), toURI.toString());
+ }
+
+ @Test(expected = MalformedURLException.class)
+ public void givenURI_whenConvertingToURL_thenException() throws MalformedURLException, URISyntaxException {
+ URI uri = new URI("somescheme://someauthority/path?thequery");
+
+ URL url = uri.toURL();
+
+ assertNotNull(url);
+ }
+
+ @Test
+ public void givenURL_whenGettingContents_thenCorrect() throws MalformedURLException, IOException {
+ URL url = new URL("http://courses.baeldung.com");
+
+ String contents = IOUtils.toString(url.openStream());
+
+ assertTrue(contents.contains(""));
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/list/listoflist/ListOfListsUnitTest.java b/core-java/src/test/java/com/baeldung/list/listoflist/ListOfListsUnitTest.java
index 7a23afa12f..5327e5f4f0 100644
--- a/core-java/src/test/java/com/baeldung/list/listoflist/ListOfListsUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/list/listoflist/ListOfListsUnitTest.java
@@ -29,12 +29,9 @@ public class ListOfListsUnitTest {
@Test
public void givenListOfLists_thenCheckNames() {
- assertEquals("Pen 1", ((Pen) listOfLists.get(0)
- .get(0)).getName());
- assertEquals("Pencil 1", ((Pencil) listOfLists.get(1)
- .get(0)).getName());
- assertEquals("Rubber 1", ((Rubber) listOfLists.get(2)
- .get(0)).getName());
+ assertEquals("Pen 1", ((Pen) listOfLists.get(0).get(0)).getName());
+ assertEquals("Pencil 1", ((Pencil) listOfLists.get(1).get(0)).getName());
+ assertEquals("Rubber 1", ((Rubber) listOfLists.get(2).get(0)).getName());
}
@SuppressWarnings("unchecked")
@@ -43,11 +40,9 @@ public class ListOfListsUnitTest {
((ArrayList) listOfLists.get(1)).remove(0);
listOfLists.remove(1);
- assertEquals("Rubber 1", ((Rubber) listOfLists.get(1)
- .get(0)).getName());
+ assertEquals("Rubber 1", ((Rubber) listOfLists.get(1).get(0)).getName());
listOfLists.remove(0);
- assertEquals("Rubber 1", ((Rubber) listOfLists.get(0)
- .get(0)).getName());
+ assertEquals("Rubber 1", ((Rubber) listOfLists.get(0).get(0)).getName());
}
@Test
@@ -67,11 +62,8 @@ public class ListOfListsUnitTest {
list.add(pencils);
list.add(rubbers);
- assertEquals("Pen 1", ((Pen) list.get(0)
- .get(0)).getName());
- assertEquals("Pencil 1", ((Pencil) list.get(1)
- .get(0)).getName());
- assertEquals("Rubber 1", ((Rubber) list.get(2)
- .get(0)).getName());
+ assertEquals("Pen 1", ((Pen) list.get(0).get(0)).getName());
+ assertEquals("Pencil 1", ((Pencil) list.get(1).get(0)).getName());
+ assertEquals("Rubber 1", ((Rubber) list.get(2).get(0)).getName());
}
}
diff --git a/core-java/src/test/java/com/baeldung/java/networking/udp/UDPIntegrationTest.java b/core-java/src/test/java/com/baeldung/networking/udp/UDPIntegrationTest.java
similarity index 95%
rename from core-java/src/test/java/com/baeldung/java/networking/udp/UDPIntegrationTest.java
rename to core-java/src/test/java/com/baeldung/networking/udp/UDPIntegrationTest.java
index aff851ae4b..968c01d24e 100644
--- a/core-java/src/test/java/com/baeldung/java/networking/udp/UDPIntegrationTest.java
+++ b/core-java/src/test/java/com/baeldung/networking/udp/UDPIntegrationTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.java.networking.udp;
+package com.baeldung.networking.udp;
import org.junit.After;
import org.junit.Before;
diff --git a/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastIntegrationTest.java b/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastIntegrationTest.java
new file mode 100644
index 0000000000..c4f1e1f42c
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastIntegrationTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.networking.udp.broadcast;
+
+import org.junit.After;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class BroadcastIntegrationTest {
+ private BroadcastingClient client;
+
+ @Test
+ public void whenBroadcasting_thenDiscoverExpectedServers() throws Exception {
+ int expectedServers = 4;
+ initializeForExpectedServers(expectedServers);
+
+ int serversDiscovered = client.discoverServers("hello server");
+ assertEquals(expectedServers, serversDiscovered);
+ }
+
+ private void initializeForExpectedServers(int expectedServers) throws Exception {
+ for (int i = 0; i < expectedServers; i++) {
+ new BroadcastingEchoServer().start();
+ }
+
+ client = new BroadcastingClient(expectedServers);
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ stopEchoServer();
+ client.close();
+ }
+
+ private void stopEchoServer() throws IOException {
+ client.discoverServers("end");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastIntegrationTest.java b/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastIntegrationTest.java
new file mode 100644
index 0000000000..404f6c4e85
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastIntegrationTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.networking.udp.multicast;
+
+import org.junit.After;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class MulticastIntegrationTest {
+ private MulticastingClient client;
+
+ @Test
+ public void whenBroadcasting_thenDiscoverExpectedServers() throws Exception {
+ int expectedServers = 4;
+ initializeForExpectedServers(expectedServers);
+
+ int serversDiscovered = client.discoverServers("hello server");
+ assertEquals(expectedServers, serversDiscovered);
+ }
+
+ private void initializeForExpectedServers(int expectedServers) throws Exception {
+ for (int i = 0; i < expectedServers; i++) {
+ new MulticastEchoServer().start();
+ }
+
+ client = new MulticastingClient(expectedServers);
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ stopEchoServer();
+ client.close();
+ }
+
+ private void stopEchoServer() throws IOException {
+ client.discoverServers("end");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java b/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java
index 9d8d3c884b..5fb85bb2c4 100644
--- a/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java
+++ b/core-java/src/test/java/com/baeldung/threadpool/CoreThreadPoolIntegrationTest.java
@@ -13,7 +13,6 @@ public class CoreThreadPoolIntegrationTest {
private static final Logger LOG = LoggerFactory.getLogger(CoreThreadPoolIntegrationTest.class);
-
@Test(timeout = 1000)
public void whenCallingExecuteWithRunnable_thenRunnableIsExecuted() throws InterruptedException {
diff --git a/ejb/ejb-client/src/main/resources/jboss-ejb-client.properties b/ejb/ejb-client/src/main/resources/jboss-ejb-client.properties
index a01a675e44..67533b7825 100755
--- a/ejb/ejb-client/src/main/resources/jboss-ejb-client.properties
+++ b/ejb/ejb-client/src/main/resources/jboss-ejb-client.properties
@@ -1,8 +1,8 @@
+endpoint.name=client-endpoint
+remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=127.0.0.1
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
-remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
-remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=${host.auth:JBOSS-LOCAL-USER}
-remote.connection.default.username=testUser
-remote.connection.default.password=admin1234!
+remote.connection.default.username=myusername
+remote.connection.default.password=mypassword
\ No newline at end of file
diff --git a/ejb/ejbclient/src/main/java/com/baeldung/ejbclient/application/TextApplication.java b/ejb/ejbclient/src/main/java/com/baeldung/ejbclient/application/TextApplication.java
new file mode 100644
index 0000000000..b65c21100d
--- /dev/null
+++ b/ejb/ejbclient/src/main/java/com/baeldung/ejbclient/application/TextApplication.java
@@ -0,0 +1,42 @@
+package com.baeldung.ejbclient.application;
+
+import com.baeldung.ejbmodule.TextProcessorBean;
+import com.baeldung.ejbmodule.TextProcessorRemote;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.Properties;
+
+public class TextApplication {
+
+ public static void main(String[] args) throws NamingException {
+ TextProcessorRemote textProcessor = EJBFactory.createTextProcessorBeanFromJNDI("ejb:");
+ System.out.print(textProcessor.processText("sample text"));
+ }
+
+ private static class EJBFactory {
+
+ private static TextProcessorRemote createTextProcessorBeanFromJNDI(String namespace) throws NamingException {
+ return lookupTextProcessorBean(namespace);
+ }
+
+ private static TextProcessorRemote lookupTextProcessorBean(String namespace) throws NamingException {
+ Context ctx = createInitialContext();
+ final String appName = "";
+ final String moduleName = "EJBModule";
+ final String distinctName = "";
+ final String beanName = TextProcessorBean.class.getSimpleName();
+ final String viewClassName = TextProcessorRemote.class.getName();
+ return (TextProcessorRemote) ctx.lookup(namespace + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
+ }
+
+ private static Context createInitialContext() throws NamingException {
+ Properties jndiProperties = new Properties();
+ jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
+ jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
+ jndiProperties.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
+ jndiProperties.put("jboss.naming.client.ejb.context", true);
+ return new InitialContext(jndiProperties);
+ }
+ }
+}
diff --git a/ejb/ejbclient/src/main/resources/jboss-ejb-client.properties b/ejb/ejbclient/src/main/resources/jboss-ejb-client.properties
new file mode 100644
index 0000000000..67533b7825
--- /dev/null
+++ b/ejb/ejbclient/src/main/resources/jboss-ejb-client.properties
@@ -0,0 +1,8 @@
+endpoint.name=client-endpoint
+remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
+remote.connections=default
+remote.connection.default.host=127.0.0.1
+remote.connection.default.port=8080
+remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
+remote.connection.default.username=myusername
+remote.connection.default.password=mypassword
\ No newline at end of file
diff --git a/ejb/ejbclient/src/test/java/com/baeldung/ejbclient/application/TextApplicationTest.java b/ejb/ejbclient/src/test/java/com/baeldung/ejbclient/application/TextApplicationTest.java
new file mode 100644
index 0000000000..947c72d0b0
--- /dev/null
+++ b/ejb/ejbclient/src/test/java/com/baeldung/ejbclient/application/TextApplicationTest.java
@@ -0,0 +1,31 @@
+package com.baeldung.ejbclient.application;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import javax.naming.NamingException;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import static org.junit.Assert.*;
+
+public class TextApplicationTest {
+
+ private static ByteArrayOutputStream outContent;
+
+ @BeforeClass
+ public static void setUpPrintStreamInstance() {
+ outContent = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outContent));
+ }
+
+ @AfterClass
+ public static void tearDownByteArrayOutputStream() {
+ outContent = null;
+ }
+
+ @Test
+ public void givenInputString_whenCompareTtoStringPrintedToConsole_thenSuccessful() throws NamingException {
+ TextApplication.main(new String[]{});
+ assertEquals("SAMPLE TEXT", outContent.toString());
+ }
+}
\ No newline at end of file
diff --git a/ejb/ejbmodule/src/main/java/com/baeldung/ejbmodule/TextProcessorBean.java b/ejb/ejbmodule/src/main/java/com/baeldung/ejbmodule/TextProcessorBean.java
new file mode 100644
index 0000000000..dc0db5fc53
--- /dev/null
+++ b/ejb/ejbmodule/src/main/java/com/baeldung/ejbmodule/TextProcessorBean.java
@@ -0,0 +1,10 @@
+package com.baeldung.ejbmodule;
+
+import javax.ejb.Stateless;
+
+@Stateless
+public class TextProcessorBean implements TextProcessorRemote {
+ public String processText(String text) {
+ return text.toUpperCase();
+ }
+}
diff --git a/ejb/ejbmodule/src/main/java/com/baeldung/ejbmodule/TextProcessorRemote.java b/ejb/ejbmodule/src/main/java/com/baeldung/ejbmodule/TextProcessorRemote.java
new file mode 100644
index 0000000000..680d8f4e10
--- /dev/null
+++ b/ejb/ejbmodule/src/main/java/com/baeldung/ejbmodule/TextProcessorRemote.java
@@ -0,0 +1,9 @@
+package com.baeldung.ejbmodule;
+
+import javax.ejb.Remote;
+
+@Remote
+public interface TextProcessorRemote {
+
+ String processText(String text);
+}
\ No newline at end of file
diff --git a/ejb/ejbmodule/src/test/java/com/baeldung/ejbmodule/TextProcessorBeanTest.java b/ejb/ejbmodule/src/test/java/com/baeldung/ejbmodule/TextProcessorBeanTest.java
new file mode 100644
index 0000000000..d8693420d4
--- /dev/null
+++ b/ejb/ejbmodule/src/test/java/com/baeldung/ejbmodule/TextProcessorBeanTest.java
@@ -0,0 +1,12 @@
+package com.baeldung.ejbmodule;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class TextProcessorBeanTest {
+ @Test
+ public void givenInputString_whenComparedToStringParsedByBean_thenSuccessful() {
+ TextProcessorBean textProcessor = new TextProcessorBean();
+ assertEquals("TEST", textProcessor.processText("test"));
+ }
+}
\ No newline at end of file
diff --git a/guest/thread-pools/pom.xml b/guest/thread-pools/pom.xml
new file mode 100644
index 0000000000..72a10213c4
--- /dev/null
+++ b/guest/thread-pools/pom.xml
@@ -0,0 +1,28 @@
+
+ 4.0.0
+ com.stackify
+ thread-pools
+ 0.0.1-SNAPSHOT
+
+
+
+ ch.qos.logback
+ logback-classic
+ 1.2.3
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.5.1
+
+ 1.8
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/guest/thread-pools/src/main/java/com/stackify/models/Employee.java b/guest/thread-pools/src/main/java/com/stackify/models/Employee.java
new file mode 100644
index 0000000000..65661f38d5
--- /dev/null
+++ b/guest/thread-pools/src/main/java/com/stackify/models/Employee.java
@@ -0,0 +1,28 @@
+package com.stackify.models;
+
+public class Employee {
+ private String name;
+ private double salary;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public double getSalary() {
+ return salary;
+ }
+
+ public void setSalary(double salary) {
+ this.salary = salary;
+ }
+
+ public Employee(String name, double salary) {
+ super();
+ this.name = name;
+ this.salary = salary;
+ }
+}
diff --git a/guest/thread-pools/src/main/java/com/stackify/services/EmployeeService.java b/guest/thread-pools/src/main/java/com/stackify/services/EmployeeService.java
new file mode 100644
index 0000000000..824f87a625
--- /dev/null
+++ b/guest/thread-pools/src/main/java/com/stackify/services/EmployeeService.java
@@ -0,0 +1,9 @@
+package com.stackify.services;
+
+import com.stackify.models.Employee;
+
+public class EmployeeService {
+ public double calculateBonus(Employee employee) {
+ return 0.1 * employee.getSalary();
+ }
+}
diff --git a/guest/thread-pools/src/main/java/com/stackify/threadpools/FactorialTask.java b/guest/thread-pools/src/main/java/com/stackify/threadpools/FactorialTask.java
new file mode 100644
index 0000000000..2dd83d9b20
--- /dev/null
+++ b/guest/thread-pools/src/main/java/com/stackify/threadpools/FactorialTask.java
@@ -0,0 +1,64 @@
+package com.stackify.threadpools;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.stream.IntStream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FactorialTask extends RecursiveTask {
+
+ private static final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ private static final long serialVersionUID = 1L;
+
+ private int start = 1;
+ private int n;
+
+ private static final int THRESHOLD = 20;
+
+ public FactorialTask(int n) {
+ this.n = n;
+ }
+
+ public FactorialTask(int start, int n) {
+ logger.info("New FactorialTask Created");
+ this.start = start;
+ this.n = n;
+ }
+
+ @Override
+ protected BigInteger compute() {
+ if ((n - start) >= THRESHOLD) {
+ return ForkJoinTask.invokeAll(createSubtasks())
+ .stream()
+ .map(ForkJoinTask::join)
+ .reduce(BigInteger.ONE, BigInteger::multiply);
+ } else {
+ return calculate(start, n);
+ }
+ }
+
+ private Collection createSubtasks() {
+ List dividedTasks = new ArrayList<>();
+
+ int mid = (start + n) / 2;
+
+ dividedTasks.add(new FactorialTask(start, mid));
+ dividedTasks.add(new FactorialTask(mid + 1, n));
+ return dividedTasks;
+ }
+
+ private BigInteger calculate(int start, int n) {
+ logger.info("Calculate factorial from " + start + " to " + n);
+ return IntStream.rangeClosed(start, n)
+ .mapToObj(BigInteger::valueOf)
+ .reduce(BigInteger.ONE, BigInteger::multiply);
+ }
+
+}
diff --git a/guest/thread-pools/src/main/java/com/stackify/threadpools/ThreadsApplication.java b/guest/thread-pools/src/main/java/com/stackify/threadpools/ThreadsApplication.java
new file mode 100644
index 0000000000..cc9048eee7
--- /dev/null
+++ b/guest/thread-pools/src/main/java/com/stackify/threadpools/ThreadsApplication.java
@@ -0,0 +1,102 @@
+package com.stackify.threadpools;
+
+import java.math.BigInteger;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.stackify.models.Employee;
+import com.stackify.services.EmployeeService;
+
+public class ThreadsApplication {
+
+ private static final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+
+ public static void main(String[] args) {
+ testExecutor();
+ testExecutorService();
+ testScheduledExecutorService();
+ testThreadPoolExecutor();
+ testForkJoinPool();
+ }
+
+ private static EmployeeService employeeService = new EmployeeService();
+
+ public static void testExecutor() {
+ Executor executor = Executors.newSingleThreadExecutor();
+ executor.execute(() -> System.out.println("Single thread pool test"));
+ }
+
+ public static void testExecutorService() {
+
+ Employee employee = new Employee("John", 2000);
+
+ ExecutorService executor = Executors.newFixedThreadPool(10);
+
+ Callable callableTask = () -> {
+ return employeeService.calculateBonus(employee);
+ };
+ Future future = executor.submit(callableTask);
+
+ try {
+ if (future.isDone()) {
+ double result = future.get();
+ System.out.println("Bonus is:" + result);
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+
+ executor.shutdown();
+ }
+
+ public static void testScheduledExecutorService() {
+ Employee employee = new Employee("John", 2000);
+
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
+
+ Callable callableTask = () -> {
+ return employeeService.calculateBonus(employee);
+ };
+
+ Future futureScheduled = executor.schedule(callableTask, 2, TimeUnit.MILLISECONDS);
+
+ try {
+ System.out.println("Bonus:" + futureScheduled.get());
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
+
+ executor.scheduleAtFixedRate(() -> System.out.println("Fixed Rate Scheduled"), 2, 2000, TimeUnit.MILLISECONDS);
+ executor.scheduleWithFixedDelay(() -> System.out.println("Fixed Delay Scheduled"), 2, 2000, TimeUnit.MILLISECONDS);
+ }
+
+ public static void testThreadPoolExecutor() {
+ ThreadPoolExecutor fixedPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
+ ThreadPoolExecutor cachedPoolExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
+
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 6, 60, TimeUnit.SECONDS, new LinkedBlockingQueue());
+ executor.setMaximumPoolSize(8);
+
+ ScheduledThreadPoolExecutor scheduledExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(5);
+ }
+
+ public static void testForkJoinPool() {
+ ForkJoinPool pool = ForkJoinPool.commonPool();
+ logger.info("Thread Pool Created");
+ BigInteger result = pool.invoke(new FactorialTask(100));
+ System.out.println(result.toString());
+ }
+}
diff --git a/jackson/pom.xml b/jackson/pom.xml
index 1a538670c6..f970b6a68c 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -129,7 +129,7 @@
- 2.8.7
+ 2.9.0
19.0
diff --git a/jackson/src/test/java/com/baeldung/jackson/sandbox/SandboxUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/sandbox/SandboxUnitTest.java
index a600577cb0..33aca2a1ed 100644
--- a/jackson/src/test/java/com/baeldung/jackson/sandbox/SandboxUnitTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/sandbox/SandboxUnitTest.java
@@ -17,7 +17,7 @@ public class SandboxUnitTest {
testElement.setX(10);
testElement.setY("adasd");
final ObjectMapper om = new ObjectMapper();
- om.setVisibilityChecker(om.getSerializationConfig().getDefaultVisibilityChecker().withFieldVisibility(JsonAutoDetect.Visibility.ANY).withGetterVisibility(JsonAutoDetect.Visibility.NONE));
+ om.setVisibility(om.getSerializationConfig().getDefaultVisibilityChecker().withFieldVisibility(JsonAutoDetect.Visibility.ANY).withGetterVisibility(JsonAutoDetect.Visibility.NONE));
final String serialized = om.writeValueAsString(testElement);
System.err.println(serialized);
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonDeserializationUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonDeserializationUnitTest.java
index 45d957b90b..035ff8ca9c 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonDeserializationUnitTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonDeserializationUnitTest.java
@@ -1,19 +1,23 @@
package com.baeldung.jackson.test;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import java.io.IOException;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.Test;
import com.baeldung.jackson.deserialization.ItemDeserializer;
import com.baeldung.jackson.dtos.Item;
import com.baeldung.jackson.dtos.ItemWithSerializer;
import com.baeldung.jackson.dtos.MyDto;
import com.baeldung.jackson.dtos.ignore.MyDtoIgnoreUnknown;
-import org.junit.Test;
-
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
@@ -21,6 +25,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -165,4 +170,35 @@ public class JacksonDeserializationUnitTest {
assertThat(readValue, notNullValue());
}
+ @Test
+ public void whenDeserialisingZonedDateTimeWithDefaults_thenTimeZoneIsNotPreserved() throws IOException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.findAndRegisterModules();
+ objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ // construct a new instance of ZonedDateTime
+ ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
+ String converted = objectMapper.writeValueAsString(now);
+ // restore an instance of ZonedDateTime from String
+ ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
+ System.out.println("serialized: " + now);
+ System.out.println("restored: " + restored);
+ assertThat(now, is(not(restored)));
+ }
+
+ @Test
+ public void whenDeserialisingZonedDateTimeWithFeaturesDisabled_thenTimeZoneIsPreserved() throws IOException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.findAndRegisterModules();
+ objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
+ // construct a new instance of ZonedDateTime
+ ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
+ String converted = objectMapper.writeValueAsString(now);
+ // restore an instance of ZonedDateTime from String
+ ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
+ System.out.println("serialized: " + now);
+ System.out.println("restored: " + restored);
+ assertThat(now, is(restored));
+ }
+
}
diff --git a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
index 71499b8a24..bc0e24cdfa 100644
--- a/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
+++ b/jackson/src/test/java/com/baeldung/jackson/test/JacksonSerializationIgnoreUnitTest.java
@@ -24,7 +24,6 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
@@ -194,7 +193,8 @@ public class JacksonSerializationIgnoreUnitTest {
@Test
public final void givenIgnoringMapNullValue_whenWritingMapObjectWithNullValue_thenIgnored() throws JsonProcessingException {
final ObjectMapper mapper = new ObjectMapper();
- mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
+ // mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
+ mapper.setSerializationInclusion(Include.NON_NULL);
final MyDto dtoObject1 = new MyDto();
diff --git a/jooq/README.md b/jooq/README.md
deleted file mode 100644
index 2f09cab46b..0000000000
--- a/jooq/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### Relevant articles
-
-- [Introduction to jOOL](http://www.baeldung.com/jool)
diff --git a/junit5/pom.xml b/junit5/pom.xml
index 2316b034e9..1fa4818447 100644
--- a/junit5/pom.xml
+++ b/junit5/pom.xml
@@ -3,7 +3,7 @@
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
+
junit5
1.0-SNAPSHOT
@@ -19,9 +19,9 @@
UTF-8
1.8
- 5.0.0-M5
- 1.0.0-M5
- 4.12.0-M5
+ 5.0.0-RC2
+ 1.0.0-RC2
+ 4.12.0-RC2
2.8.2
1.4.196
diff --git a/junit5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java b/junit5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java
new file mode 100644
index 0000000000..67bd47a44a
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java
@@ -0,0 +1,50 @@
+package com.baeldung.param;
+
+import java.util.Random;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class InvalidPersonParameterResolver implements ParameterResolver {
+
+ /**
+ * The "bad" (invalid) data for testing purposes has to go somewhere, right?
+ */
+ public static Person[] INVALID_PERSONS = {
+ new Person().setId(1L).setLastName("Ad_ams").setFirstName("Jill,"),
+ new Person().setId(2L).setLastName(",Baker").setFirstName(""),
+ new Person().setId(3L).setLastName(null).setFirstName(null),
+ new Person().setId(4L).setLastName("Daniel&").setFirstName("{Joseph}"),
+ new Person().setId(5L).setLastName("").setFirstName("English, Jane"),
+ new Person()/* .setId(6L).setLastName("Fontana").setFirstName("Enrique") */,
+ // TODO: ADD MORE DATA HERE
+ };
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
+ throws ParameterResolutionException {
+ Object ret = null;
+ //
+ // Return a random, valid Person object if Person.class is the type of Parameter
+ /// to be resolved. Otherwise return null.
+ if (parameterContext.getParameter().getType() == Person.class) {
+ ret = INVALID_PERSONS[new Random().nextInt(INVALID_PERSONS.length)];
+ }
+ return ret;
+ }
+
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
+ throws ParameterResolutionException {
+ boolean ret = false;
+ //
+ // If the Parameter.type == Person.class, then we support it, otherwise, get outta here!
+ if (parameterContext.getParameter().getType() == Person.class) {
+ ret = true;
+ }
+ return ret;
+ }
+
+}
diff --git a/junit5/src/test/java/com/baeldung/param/Person.java b/junit5/src/test/java/com/baeldung/param/Person.java
new file mode 100644
index 0000000000..65333b5e56
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/param/Person.java
@@ -0,0 +1,43 @@
+package com.baeldung.param;
+
+/**
+ * Very simple Person entity.
+ * Use the Fluent-style interface to set properties.
+ *
+ * @author J Steven Perry
+ *
+ */
+public class Person {
+
+ private Long id;
+ private String lastName;
+ private String firstName;
+
+ public Long getId() {
+ return id;
+ }
+
+ public Person setId(Long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public Person setLastName(String lastName) {
+ this.lastName = lastName;
+ return this;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public Person setFirstName(String firstName) {
+ this.firstName = firstName;
+ return this;
+ }
+
+}
diff --git a/junit5/src/test/java/com/baeldung/param/PersonValidator.java b/junit5/src/test/java/com/baeldung/param/PersonValidator.java
new file mode 100644
index 0000000000..0219169aab
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/param/PersonValidator.java
@@ -0,0 +1,142 @@
+package com.baeldung.param;
+
+import java.util.Arrays;
+
+/**
+ * Somewhat contrived validation class to illustrate unit test
+ * concepts.
+ *
+ * @author J Steven Perry
+ *
+ */
+public class PersonValidator {
+
+ /**
+ * Contrived checked exception to illustrate one possible
+ * way to handle validation errors (via a checked exception).
+ *
+ * @author J Steven Perry
+ *
+ */
+ public static class ValidationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -134518049431883102L;
+
+ // Probably should implement some more constructors, but don't want
+ /// to tarnish the lesson...
+
+ /**
+ * The one and only way to create this checked exception.
+ *
+ * @param message
+ * The message accompanying the exception. Should be meaningful.
+ */
+ public ValidationException(String message) {
+ super(message);
+
+ }
+
+ }
+
+ private static final String[] ILLEGAL_NAME_CHARACTERS = {
+ ",",
+ "_",
+ "{",
+ "}",
+ "!"
+ };
+
+ /**
+ * Validate the first name of the specified Person object.
+ *
+ * @param person
+ * The Person object to validate.
+ *
+ * @return - returns true if the specified Person is valid
+ *
+ * @throws ValidationException
+ * - this Exception is thrown if any kind of validation error occurs.
+ */
+ public static boolean validateFirstName(Person person) throws ValidationException {
+ boolean ret = true;
+ // The validation rules go here.
+ // Naive: use simple ifs
+ if (person == null) {
+ throw new ValidationException("Person is null (not allowed)!");
+ }
+ if (person.getFirstName() == null) {
+ throw new ValidationException("Person FirstName is null (not allowed)!");
+ }
+ if (person.getFirstName().isEmpty()) {
+ throw new ValidationException("Person FirstName is an empty String (not allowed)!");
+ }
+ if (!isStringValid(person.getFirstName(), ILLEGAL_NAME_CHARACTERS)) {
+ throw new ValidationException(
+ "Person FirstName (" + person.getFirstName() + ") may not contain any of the following characters: "
+ + Arrays.toString(ILLEGAL_NAME_CHARACTERS)
+ + "!");
+ }
+ return ret;
+ }
+
+ /**
+ * Validate the last name of the specified Person object. Looks the same as first
+ * name? Look closer. Just kidding. It's the same. But real world code can (and will) diverge.
+ *
+ * @param person
+ * The Person object to validate.
+ *
+ * @return - returns true if the specified Person is valid
+ *
+ * @throws ValidationException
+ * - this Exception is thrown if any kind of validation error occurs.
+ */
+ public static boolean validateLastName(Person person) throws ValidationException {
+ boolean ret = true;
+ // The validation rules go here.
+ // Naive: use simple ifs
+ if (person == null) {
+ throw new ValidationException("Person is null (not allowed)!");
+ }
+ if (person.getFirstName() == null) {
+ throw new ValidationException("Person FirstName is null (not allowed)!");
+ }
+ if (person.getFirstName().isEmpty()) {
+ throw new ValidationException("Person FirstName is an empty String (not allowed)!");
+ }
+ if (!isStringValid(person.getFirstName(), ILLEGAL_NAME_CHARACTERS)) {
+ throw new ValidationException(
+ "Person LastName (" + person.getLastName() + ") may not contain any of the following characters: "
+ + Arrays.toString(ILLEGAL_NAME_CHARACTERS)
+ + "!");
+ }
+ return ret;
+ }
+
+ /**
+ * Validates the specified name. If it contains any of the illegalCharacters,
+ * this method returns false (indicating the name is illegal). Otherwise it returns true.
+ *
+ * @param candidate
+ * The candidate String to validate
+ *
+ * @param illegalCharacters
+ * The characters the String is not allowed to have
+ *
+ * @return - boolean - true if the name is valid, false otherwise.
+ */
+ private static boolean isStringValid(String candidate, String[] illegalCharacters) {
+ boolean ret = true;
+ for (String illegalChar : illegalCharacters) {
+ if (candidate.contains(illegalChar)) {
+ ret = false;
+ break;
+ }
+ }
+ return ret;
+ }
+
+}
diff --git a/junit5/src/test/java/com/baeldung/param/PersonValidatorTest.java b/junit5/src/test/java/com/baeldung/param/PersonValidatorTest.java
new file mode 100644
index 0000000000..09ab03b811
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/param/PersonValidatorTest.java
@@ -0,0 +1,102 @@
+package com.baeldung.param;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.RepeatedTest;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.runner.RunWith;
+
+@RunWith(JUnitPlatform.class)
+@DisplayName("Testing PersonValidator")
+public class PersonValidatorTest {
+
+ /**
+ * Nested class, uses ExtendWith
+ * {@link com.baeldung.param.ValidPersonParameterResolver ValidPersonParameterResolver}
+ * to feed Test methods with "good" data.
+ */
+ @Nested
+ @DisplayName("When using Valid data")
+ @ExtendWith(ValidPersonParameterResolver.class)
+ public class ValidData {
+
+ /**
+ * Repeat the test ten times, that way we have a good shot at
+ * running all of the data through at least once.
+ *
+ * @param person
+ * A valid Person object to validate.
+ */
+ @RepeatedTest(value = 10)
+ @DisplayName("All first names are valid")
+ public void validateFirstName(Person person) {
+ try {
+ assertTrue(PersonValidator.validateFirstName(person));
+ } catch (PersonValidator.ValidationException e) {
+ fail("Exception not expected: " + e.getLocalizedMessage());
+ }
+ }
+
+ /**
+ * Repeat the test ten times, that way we have a good shot at
+ * running all of the data through at least once.
+ *
+ * @param person
+ * A valid Person object to validate.
+ */
+ @RepeatedTest(value = 10)
+ @DisplayName("All last names are valid")
+ public void validateLastName(Person person) {
+ try {
+ assertTrue(PersonValidator.validateLastName(person));
+ } catch (PersonValidator.ValidationException e) {
+ fail("Exception not expected: " + e.getLocalizedMessage());
+ }
+ }
+
+ }
+
+ /**
+ * Nested class, uses ExtendWith
+ * {@link com.baeldung.param.InvalidPersonParameterResolver InvalidPersonParameterResolver}
+ * to feed Test methods with "bad" data.
+ */
+ @Nested
+ @DisplayName("When using Invalid data")
+ @ExtendWith(InvalidPersonParameterResolver.class)
+ public class InvalidData {
+
+ /**
+ * Repeat the test ten times, that way we have a good shot at
+ * running all of the data through at least once.
+ *
+ * @param person
+ * An invalid Person object to validate.
+ */
+ @RepeatedTest(value = 10)
+ @DisplayName("All first names are invalid")
+ public void validateFirstName(Person person) {
+ assertThrows(PersonValidator.ValidationException.class, () -> PersonValidator.validateFirstName(person));
+ }
+
+ /**
+ * Repeat the test ten times, that way we have a good shot at
+ * running all of the data through at least once.
+ *
+ * @param person
+ * An invalid Person object to validate.
+ */
+ @RepeatedTest(value = 10)
+ @DisplayName("All first names are invalid")
+ public void validateLastName(Person person) {
+ assertThrows(PersonValidator.ValidationException.class, () -> PersonValidator.validateLastName(person));
+ }
+
+ }
+
+}
diff --git a/junit5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java b/junit5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java
new file mode 100644
index 0000000000..abb97586eb
--- /dev/null
+++ b/junit5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java
@@ -0,0 +1,50 @@
+package com.baeldung.param;
+
+import java.util.Random;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class ValidPersonParameterResolver implements ParameterResolver {
+
+ /**
+ * The "good" (valid) data for testing purposes has to go somewhere, right?
+ */
+ public static Person[] VALID_PERSONS = {
+ new Person().setId(1L).setLastName("Adams").setFirstName("Jill"),
+ new Person().setId(2L).setLastName("Baker").setFirstName("James"),
+ new Person().setId(3L).setLastName("Carter").setFirstName("Samanta"),
+ new Person().setId(4L).setLastName("Daniels").setFirstName("Joseph"),
+ new Person().setId(5L).setLastName("English").setFirstName("Jane"),
+ new Person().setId(6L).setLastName("Fontana").setFirstName("Enrique"),
+ // TODO: ADD MORE DATA HERE
+ };
+
+ @Override
+ public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
+ throws ParameterResolutionException {
+ Object ret = null;
+ //
+ // Return a random, valid Person object if Person.class is the type of Parameter
+ /// to be resolved. Otherwise return null.
+ if (parameterContext.getParameter().getType() == Person.class) {
+ ret = VALID_PERSONS[new Random().nextInt(VALID_PERSONS.length)];
+ }
+ return ret;
+ }
+
+ @Override
+ public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
+ throws ParameterResolutionException {
+ boolean ret = false;
+ //
+ // If the Parameter.type == Person.class, then we support it, otherwise, get outta here!
+ if (parameterContext.getParameter().getType() == Person.class) {
+ ret = true;
+ }
+ return ret;
+ }
+
+}
diff --git a/kotlin/README.md b/kotlin/README.md
index 6b3fb93dcc..91933e94dc 100644
--- a/kotlin/README.md
+++ b/kotlin/README.md
@@ -7,3 +7,10 @@
- [Difference Between “==” and “===” in Kotlin](http://www.baeldung.com/kotlin-equality-operators)
- [Generics in Kotlin](http://www.baeldung.com/kotlin-generics)
- [Introduction to Kotlin Coroutines](http://www.baeldung.com/kotlin-coroutines)
+- [Destructuring Declarations in Kotlin](http://www.baeldung.com/kotlin-destructuring-declarations)
+- [Kotlin with Mockito](http://www.baeldung.com/kotlin-mockito)
+- [Lazy Initialization in Kotlin](http://www.baeldung.com/kotlin-lazy-initialization)
+- [Overview of Kotlin Collections API](http://www.baeldung.com/kotlin-collections-api)
+- [Converting a List to Map in Kotlin](http://www.baeldung.com/kotlin-list-to-map)
+- [Data Classes in Kotlin](http://www.baeldung.com/kotlin-data-classes)
+
diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt b/kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt
new file mode 100644
index 0000000000..96e54716b3
--- /dev/null
+++ b/kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt
@@ -0,0 +1,19 @@
+package com.baeldung.kotlin
+
+sealed class Result {
+ abstract fun map(func: (S) -> R) : Result
+ abstract fun mapFailure(func: (F) -> R) : Result
+ abstract fun get() : S?
+}
+
+data class Success(val success: S) : Result() {
+ override fun map(func: (S) -> R) : Result = Success(func(success))
+ override fun mapFailure(func: (F) -> R): Result = Success(success)
+ override fun get(): S? = success
+}
+
+data class Failure(val failure: F) : Result() {
+ override fun map(func: (S) -> R) : Result = Failure(failure)
+ override fun mapFailure(func: (F) -> R): Result = Failure(func(failure))
+ override fun get(): S? = null
+}
diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt b/kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt
new file mode 100644
index 0000000000..8c7509f653
--- /dev/null
+++ b/kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt
@@ -0,0 +1,84 @@
+package com.baeldung.kotlin
+
+import org.junit.Assert
+import org.junit.Test
+
+class SealedTest {
+ fun divide(a: Int, b: Int) : Result = when (b) {
+ 0 -> Failure("Division by zero")
+ else -> Success(a.toFloat() / b)
+ }
+
+ @Test
+ fun testSuccess() {
+ val result = divide(10, 5)
+ Assert.assertEquals(Success(2.0f), result)
+ }
+
+ @Test
+ fun testError() {
+ val result = divide(10, 0)
+ Assert.assertEquals(Failure("Division by zero"), result)
+ }
+
+ @Test
+ fun testMatchOnSuccess() {
+ val result = divide(10, 5)
+ when (result) {
+ is Success -> {
+ // Expected
+ }
+ is Failure -> Assert.fail("Expected Success")
+ }
+ }
+
+ @Test
+ fun testMatchOnError() {
+ val result = divide(10, 0)
+ when (result) {
+ is Failure -> {
+ // Expected
+ }
+ }
+ }
+
+ @Test
+ fun testGetSuccess() {
+ val result = divide(10, 5)
+ Assert.assertEquals(2.0f, result.get())
+ }
+
+ @Test
+ fun testGetError() {
+ val result = divide(10, 0)
+ Assert.assertNull(result.get())
+ }
+
+ @Test
+ fun testMapOnSuccess() {
+ val result = divide(10, 5)
+ .map { "Result: $it" }
+ Assert.assertEquals(Success("Result: 2.0"), result)
+ }
+
+ @Test
+ fun testMapOnError() {
+ val result = divide(10, 0)
+ .map { "Result: $it" }
+ Assert.assertEquals(Failure("Division by zero"), result)
+ }
+
+ @Test
+ fun testMapFailureOnSuccess() {
+ val result = divide(10, 5)
+ .mapFailure { "Failure: $it" }
+ Assert.assertEquals(Success(2.0f), result)
+ }
+
+ @Test
+ fun testMapFailureOnError() {
+ val result = divide(10, 0)
+ .mapFailure { "Failure: $it" }
+ Assert.assertEquals(Failure("Failure: Division by zero"), result)
+ }
+}
diff --git a/libraries/README.md b/libraries/README.md
index 86baa39045..ed6d214c7a 100644
--- a/libraries/README.md
+++ b/libraries/README.md
@@ -23,11 +23,15 @@
- [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave)
- [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing)
- [Apache Commons Collections OrderedMap](http://www.baeldung.com/apache-commons-ordered-map)
+- [Introduction to Apache Commons Text](http://www.baeldung.com/java-apache-commons-text)
- [A Guide to Apache Commons DbUtils](http://www.baeldung.com/apache-commons-dbutils)
- [Introduction to Awaitility](http://www.baeldung.com/awaitlity-testing)
- [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog)
- [Introduction to Neuroph](http://www.baeldung.com/intro-to-neuroph)
- [Guide to Apache Commons CircularFifoQueue](http://www.baeldung.com/commons-circular-fifo-queue)
+- [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss)
+- [Introduction to NoException](http://www.baeldung.com/intrduction-to-noexception)
+
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.
diff --git a/libraries/pom.xml b/libraries/pom.xml
index efdf20423a..cf77d197a2 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -1,501 +1,568 @@
-
- parent-modules
- com.baeldung
- 1.0.0-SNAPSHOT
-
- 4.0.0
- libraries
- libraries
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- org.apache.felix
- maven-bundle-plugin
- 3.3.0
- maven-plugin
-
-
- true
-
-
- maven-failsafe-plugin
- 2.20
-
-
- chromedriver
-
-
-
-
- net.serenity-bdd.maven.plugins
- serenity-maven-plugin
- ${serenity.plugin.version}
-
-
- serenity-reports
- post-integration-test
-
- aggregate
-
-
-
-
-
-
- org.datanucleus
- datanucleus-maven-plugin
- 5.0.2
-
- JDO
- ${basedir}/datanucleus.properties
- ${basedir}/log4j.properties
- true
- false
-
-
-
-
- process-classes
-
- enhance
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.0.2
-
-
- **/log4j.properties
-
-
-
- com.baeldung.neuroph.NeurophXOR
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 2.18.1
-
-
- test
- test
-
- test
-
-
-
- test/java/com/baeldung/neuroph/XORTest.java
-
-
-
-
-
-
-
-
-
-
-
- org.beykery
- neuroph
- ${neuroph.version}
-
-
-
- cglib
- cglib
- ${cglib.version}
-
-
- commons-beanutils
- commons-beanutils
- ${commons-beanutils.version}
-
-
- org.apache.commons
- commons-lang3
- ${commons-lang.version}
-
-
- org.apache.commons
- commons-text
- ${commons-text.version}
-
-
- org.apache.commons
- commons-collections4
- ${commons.collections.version}
-
-
- org.jasypt
- jasypt
- ${jasypt.version}
-
-
- org.javatuples
- javatuples
- ${javatuples.version}
-
-
- org.javassist
- javassist
- ${javaassist.version}
-
-
-
- org.assertj
- assertj-core
- ${assertj.version}
-
-
- org.skyscreamer
- jsonassert
- ${jsonassert.version}
-
-
- org.javers
- javers-core
- ${javers.version}
-
-
- org.eclipse.jetty
- jetty-server
- ${jetty.version}
-
-
- org.eclipse.jetty
- jetty-servlet
- ${jetty.version}
-
-
- io.specto
- hoverfly-java
- 0.8.0
-
-
- org.apache.httpcomponents
- httpclient
- ${httpclient.version}
-
-
- commons-logging
- commons-logging
-
-
-
-
- commons-io
- commons-io
- ${commons.io.version}
-
-
- commons-chain
- commons-chain
- ${commons-chain.version}
-
-
- commons-dbutils
- commons-dbutils
- ${commons.dbutils.version}
-
-
- org.apache.flink
- flink-core
- ${flink.version}
-
-
- commons-logging
- commons-logging
-
-
-
-
- org.apache.flink
- flink-java
- ${flink.version}
-
-
- commons-logging
- commons-logging
-
-
-
-
- org.apache.flink
- flink-test-utils_2.10
- ${flink.version}
- test
-
-
- org.apache.commons
- commons-math3
- 3.6.1
-
-
- net.serenity-bdd
- serenity-core
- ${serenity.version}
- test
-
-
- net.serenity-bdd
- serenity-junit
- ${serenity.version}
- test
-
-
- net.serenity-bdd
- serenity-jbehave
- ${serenity.jbehave.version}
- test
-
-
- net.serenity-bdd
- serenity-rest-assured
- ${serenity.version}
- test
-
-
- net.serenity-bdd
- serenity-jira-requirements-provider
- ${serenity.jira.version}
- test
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
-
- org.datanucleus
- javax.jdo
- 3.2.0-m6
-
-
- org.datanucleus
- datanucleus-core
- 5.1.0-m1
-
-
- org.datanucleus
- datanucleus-api-jdo
- 5.1.0-m1
-
-
- org.datanucleus
- datanucleus-rdbms
- 5.1.0-m1
-
-
- org.datanucleus
- datanucleus-maven-plugin
- 5.0.2
-
-
- org.datanucleus
- datanucleus-xml
- 5.0.0-release
-
-
- net.openhft
- chronicle
- 3.6.4
-
-
- org.springframework
- spring-web
- 4.3.8.RELEASE
-
-
- net.serenity-bdd
- serenity-spring
- ${serenity.version}
- test
-
-
- net.serenity-bdd
- serenity-screenplay
- ${serenity.version}
- test
-
-
- net.serenity-bdd
- serenity-screenplay-webdriver
- ${serenity.version}
- test
-
-
- io.rest-assured
- spring-mock-mvc
- 3.0.3
- test
-
-
- org.multiverse
- multiverse-core
- ${multiverse.version}
-
-
- com.zaxxer
- HikariCP
- 2.6.1
- compile
-
-
- com.h2database
- h2
- ${h2.version}
-
-
- pl.pragmatists
- JUnitParams
- ${jUnitParams.version}
- test
-
-
- org.quartz-scheduler
- quartz
- 2.3.0
-
-
- one.util
- streamex
- 0.6.5
-
-
- org.jooq
- jool
- 0.9.12
-
-
- org.openjdk.jmh
- jmh-core
- 1.19
-
-
- org.openjdk.jmh
- jmh-generator-annprocess
- 1.19
-
-
- io.netty
- netty-all
- ${netty.version}
-
-
- junit
- junit
- ${junit.version}
- test
-
-
- info.debatty
- java-lsh
- ${java-lsh.version}
-
-
- au.com.dius
- pact-jvm-consumer-junit_2.11
- ${pact.version}
- test
-
-
- org.codehaus.groovy
- groovy-all
- 2.4.10
-
-
- org.awaitility
- awaitility
- ${awaitility.version}
- test
-
-
- org.awaitility
- awaitility-proxy
- ${awaitility.version}
- test
-
-
- org.hamcrest
- java-hamcrest
- ${org.hamcrest.java-hamcrest.version}
- test
-
-
- net.agkn
- hll
- ${hll.version}
-
-
- net.bytebuddy
- byte-buddy
- ${bytebuddy.version}
-
-
- net.bytebuddy
- byte-buddy-agent
- ${bytebuddy.version}
-
-
- org.pcollections
- pcollections
- ${pcollections.version}
-
-
-
- 0.7.0
- 3.2.4
- 3.5
- 1.1
- 1.9.3
- 1.2
- 1.9.2
- 1.2
- 3.21.0-GA
- 3.6.2
- 1.5.0
- 3.1.0
- 9.4.3.v20170317
- 4.5.3
- 2.5
- 1.6
- 1.4.196
- 9.4.2.v20170220
- 4.5.3
- 2.5
- 1.2.0
- 2.8.5
- 2.92
- 1.4.0
- 1.24.0
- 1.1.3-rc.5
- 1.4.0
- 1.1.0
- 4.1.10.Final
- 4.1
- 4.12
- 0.10
- 3.5.0
- 3.0.0
- 2.0.0.0
- 1.6.0
- 1.7.1
- 2.1.2
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+ libraries
+ libraries
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 3.3.0
+ maven-plugin
+
+
+ true
+
+
+ maven-failsafe-plugin
+ 2.20
+
+
+ chromedriver
+
+
+
+
+ net.serenity-bdd.maven.plugins
+ serenity-maven-plugin
+ ${serenity.plugin.version}
+
+
+ serenity-reports
+ post-integration-test
+
+ aggregate
+
+
+
+
+
+
+ org.datanucleus
+ datanucleus-maven-plugin
+ 5.0.2
+
+ JDO
+ ${basedir}/datanucleus.properties
+ ${basedir}/log4j.properties
+ true
+ false
+
+
+
+
+ process-classes
+
+ enhance
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.0.2
+
+
+ **/log4j.properties
+
+
+
+ com.baeldung.neuroph.NeurophXOR
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.18.1
+
+
+ test
+ test
+
+ test
+
+
+
+ test/java/com/baeldung/neuroph/XORTest.java
+
+
+
+
+
+
+
+
+
+
+
+ org.beykery
+ neuroph
+ ${neuroph.version}
+
+
+
+ cglib
+ cglib
+ ${cglib.version}
+
+
+ commons-beanutils
+ commons-beanutils
+ ${commons-beanutils.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang.version}
+
+
+ org.apache.commons
+ commons-text
+ ${commons-text.version}
+
+
+ org.apache.commons
+ commons-collections4
+ ${commons.collections.version}
+
+
+ org.jasypt
+ jasypt
+ ${jasypt.version}
+
+
+ org.javatuples
+ javatuples
+ ${javatuples.version}
+
+
+ org.javassist
+ javassist
+ ${javaassist.version}
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+
+
+ org.skyscreamer
+ jsonassert
+ ${jsonassert.version}
+
+
+ org.javers
+ javers-core
+ ${javers.version}
+
+
+ org.eclipse.jetty
+ jetty-server
+ ${jetty.version}
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ ${jetty.version}
+
+
+ rome
+ rome
+ ${rome.version}
+
+
+ io.specto
+ hoverfly-java
+ 0.8.0
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ commons-io
+ commons-io
+ ${commons.io.version}
+
+
+ commons-chain
+ commons-chain
+ ${commons-chain.version}
+
+
+ org.apache.commons
+ commons-csv
+ ${commons-csv.version}
+
+
+ commons-dbutils
+ commons-dbutils
+ ${commons.dbutils.version}
+
+
+ org.apache.flink
+ flink-core
+ ${flink.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.apache.flink
+ flink-java
+ ${flink.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.apache.flink
+ flink-test-utils_2.10
+ ${flink.version}
+ test
+
+
+ org.apache.commons
+ commons-math3
+ 3.6.1
+
+
+ net.serenity-bdd
+ serenity-core
+ ${serenity.version}
+ test
+
+
+ net.serenity-bdd
+ serenity-junit
+ ${serenity.version}
+ test
+
+
+ net.serenity-bdd
+ serenity-jbehave
+ ${serenity.jbehave.version}
+ test
+
+
+ net.serenity-bdd
+ serenity-rest-assured
+ ${serenity.version}
+ test
+
+
+ net.serenity-bdd
+ serenity-jira-requirements-provider
+ ${serenity.jira.version}
+ test
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
+ org.datanucleus
+ javax.jdo
+ 3.2.0-m6
+
+
+ org.datanucleus
+ datanucleus-core
+ 5.1.0-m1
+
+
+ org.datanucleus
+ datanucleus-api-jdo
+ 5.1.0-m1
+
+
+ org.datanucleus
+ datanucleus-rdbms
+ 5.1.0-m1
+
+
+ org.datanucleus
+ datanucleus-maven-plugin
+ 5.0.2
+
+
+ org.datanucleus
+ datanucleus-xml
+ 5.0.0-release
+
+
+ net.openhft
+ chronicle
+ 3.6.4
+
+
+ org.springframework
+ spring-web
+ 4.3.8.RELEASE
+
+
+ net.serenity-bdd
+ serenity-spring
+ ${serenity.version}
+ test
+
+
+ net.serenity-bdd
+ serenity-screenplay
+ ${serenity.version}
+ test
+
+
+ net.serenity-bdd
+ serenity-screenplay-webdriver
+ ${serenity.version}
+ test
+
+
+ io.rest-assured
+ spring-mock-mvc
+ 3.0.3
+ test
+
+
+ org.multiverse
+ multiverse-core
+ ${multiverse.version}
+
+
+ com.zaxxer
+ HikariCP
+ 2.6.1
+ compile
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ pl.pragmatists
+ JUnitParams
+ ${jUnitParams.version}
+ test
+
+
+ org.quartz-scheduler
+ quartz
+ 2.3.0
+
+
+ one.util
+ streamex
+ ${streamex.version}
+
+
+ org.jooq
+ jool
+ 0.9.12
+
+
+ org.openjdk.jmh
+ jmh-core
+ 1.19
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ 1.19
+
+
+ io.netty
+ netty-all
+ ${netty.version}
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+ info.debatty
+ java-lsh
+ ${java-lsh.version}
+
+
+ au.com.dius
+ pact-jvm-consumer-junit_2.11
+ ${pact.version}
+ test
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.10
+
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ org.awaitility
+ awaitility-proxy
+ ${awaitility.version}
+ test
+
+
+ org.hamcrest
+ java-hamcrest
+ ${org.hamcrest.java-hamcrest.version}
+ test
+
+
+ net.agkn
+ hll
+ ${hll.version}
+
+
+ net.bytebuddy
+ byte-buddy
+ ${bytebuddy.version}
+
+
+ net.bytebuddy
+ byte-buddy-agent
+ ${bytebuddy.version}
+
+
+ org.pcollections
+ pcollections
+ ${pcollections.version}
+
+
+ com.machinezoo.noexception
+ noexception
+ 1.1.0
+
+
+ org.eclipse.collections
+ eclipse-collections
+ ${eclipse-collections.version}
+
+
+ io.vavr
+ vavr
+ ${vavr.version}
+
+
+ org.geotools
+ gt-shapefile
+ ${geotools.version}
+
+
+ org.geotools
+ gt-epsg-hsql
+ ${geotools.version}
+
+
+ org.geotools
+ gt-swing
+ ${geotools.version}
+
+
+
+
+ maven2-repository.dev.java.net
+ Java.net repository
+ http://download.java.net/maven/2
+
+
+ osgeo
+ Open Source Geospatial Foundation Repository
+ http://download.osgeo.org/webdav/geotools/
+
+
+
+ true
+
+ opengeo
+ OpenGeo Maven Repository
+ http://repo.opengeo.org
+
+
+
+ 0.7.0
+ 3.2.4
+ 3.5
+ 1.1
+ 1.9.3
+ 1.2
+ 1.4
+ 1.9.2
+ 1.2
+ 3.21.0-GA
+ 3.6.2
+ 1.5.0
+ 3.1.0
+ 9.4.3.v20170317
+ 4.5.3
+ 2.5
+ 1.6
+ 1.4.196
+ 9.4.2.v20170220
+ 4.5.3
+ 2.5
+ 1.2.0
+ 2.8.5
+ 2.92
+ 1.4.0
+ 1.24.0
+ 1.1.3-rc.5
+ 1.4.0
+ 1.1.0
+ 4.1.10.Final
+ 4.1
+ 4.12
+ 0.10
+ 3.5.0
+ 3.0.0
+ 2.0.0.0
+ 1.6.0
+ 1.7.1
+ 2.1.2
+ 1.0
+ 8.2.0
+ 0.6.5
+ 0.9.0
+ 15.2
+
+
diff --git a/libraries/src/main/java/com/baeldung/distinct/DistinctWithJavaFunction.java b/libraries/src/main/java/com/baeldung/distinct/DistinctWithJavaFunction.java
new file mode 100644
index 0000000000..0d08c94b47
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/distinct/DistinctWithJavaFunction.java
@@ -0,0 +1,15 @@
+package com.baeldung.distinct;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class DistinctWithJavaFunction {
+
+ public static Predicate distinctByKey(Function super T, ?> keyExtractor) {
+ Map
diff --git a/pom.xml b/pom.xml
index 3feba96d5a..f2dd0ae48c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,7 @@
apache-thrift
autovalue
axon
+ bootique
cdi
@@ -80,10 +81,9 @@
javax-servlets
javaxval
jaxb
-
+ jee7
jjwt
- jooq
jpa-storedprocedure
jsf
json-path
@@ -106,6 +106,7 @@
mockito2
mocks
mustache
+ noexception
orika
@@ -174,6 +175,7 @@
spring-mvc-webflow
spring-mvc-xml
spring-mvc-simple
+ spring-mvc-kotlin
spring-security-openid
spring-protobuf
spring-quartz
@@ -236,6 +238,7 @@
liquibase
spring-boot-property-exp
mockserver
+ undertow
diff --git a/ratpack/README.md b/ratpack/README.md
index 91c8e025f0..8215f74148 100644
--- a/ratpack/README.md
+++ b/ratpack/README.md
@@ -2,3 +2,4 @@
- [Introduction to Ratpack](http://www.baeldung.com/ratpack)
- [Ratpack Google Guice Integration](http://www.baeldung.com/ratpack-google-guice)
+- [Ratpack Integration with Spring Boot](http://www.baeldung.com/ratpack-spring-boot)
diff --git a/rule-engines/easy-rules/pom.xml b/rule-engines/easy-rules/pom.xml
new file mode 100644
index 0000000000..78edc09d1a
--- /dev/null
+++ b/rule-engines/easy-rules/pom.xml
@@ -0,0 +1,24 @@
+
+ 4.0.0
+
+ com.baeldung.easyrules
+ easy-rules
+ 1.0
+
+ easy-rules
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.jeasy
+ easy-rules-core
+ 3.0.0
+
+
+
\ No newline at end of file
diff --git a/rule-engines/easy-rules/src/main/java/com/baeldung/easyrules/HelloWorldRule.java b/rule-engines/easy-rules/src/main/java/com/baeldung/easyrules/HelloWorldRule.java
new file mode 100644
index 0000000000..5448eabf2a
--- /dev/null
+++ b/rule-engines/easy-rules/src/main/java/com/baeldung/easyrules/HelloWorldRule.java
@@ -0,0 +1,20 @@
+package com.baeldung.easyrules;
+
+import org.jeasy.rules.annotation.Action;
+import org.jeasy.rules.annotation.Condition;
+import org.jeasy.rules.annotation.Rule;
+
+@Rule(name = "Hello World rule", description = "Always say hello world")
+public class HelloWorldRule {
+
+ @Condition
+ public boolean when() {
+ return true;
+ }
+
+ @Action
+ public void then() throws Exception {
+ System.out.println("hello world");
+ }
+
+}
diff --git a/rule-engines/easy-rules/src/main/java/com/baeldung/easyrules/Launcher.java b/rule-engines/easy-rules/src/main/java/com/baeldung/easyrules/Launcher.java
new file mode 100644
index 0000000000..427e3eace0
--- /dev/null
+++ b/rule-engines/easy-rules/src/main/java/com/baeldung/easyrules/Launcher.java
@@ -0,0 +1,21 @@
+package com.baeldung.easyrules;
+
+import org.jeasy.rules.api.Facts;
+import org.jeasy.rules.api.Rules;
+import org.jeasy.rules.api.RulesEngine;
+import org.jeasy.rules.core.DefaultRulesEngine;
+
+public class Launcher {
+ public static void main(String... args) {
+ // create facts
+ Facts facts = new Facts();
+
+ // create rules
+ Rules rules = new Rules();
+ rules.register(new HelloWorldRule());
+
+ // create a rules engine and fire rules on known facts
+ RulesEngine rulesEngine = new DefaultRulesEngine();
+ rulesEngine.fire(rules, facts);
+ }
+}
diff --git a/rule-engines/openl-tablets/pom.xml b/rule-engines/openl-tablets/pom.xml
new file mode 100644
index 0000000000..e983d4e566
--- /dev/null
+++ b/rule-engines/openl-tablets/pom.xml
@@ -0,0 +1,29 @@
+
+ 4.0.0
+
+ com.baeldung.openltablets
+ openl-tablets
+ 1.0
+
+ openl-tablets
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.openl
+ org.openl.core
+ 5.19.4
+
+
+ org.openl.rules
+ org.openl.rules
+ 5.19.4
+
+
+
\ No newline at end of file
diff --git a/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/Case.java b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/Case.java
new file mode 100644
index 0000000000..f9f5f4bd5f
--- /dev/null
+++ b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/Case.java
@@ -0,0 +1,23 @@
+package com.baeldung.openltablets.model;
+
+public class Case {
+
+ private User user;
+ private int hourOfDay;
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(final User user) {
+ this.user = user;
+ }
+
+ public int getHourOfDay() {
+ return hourOfDay;
+ }
+
+ public void setHourOfDay(final int hourOfDay) {
+ this.hourOfDay = hourOfDay;
+ }
+}
diff --git a/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/Greeting.java b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/Greeting.java
new file mode 100644
index 0000000000..5dc7bcd117
--- /dev/null
+++ b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/Greeting.java
@@ -0,0 +1,20 @@
+package com.baeldung.openltablets.model;
+
+public enum Greeting {
+
+ GOOD_MORNING("Good Morning"),
+ GOOD_AFTERNOON("Good Afternoon"),
+ GOOD_EVENING("Good Evening"),
+ GOOD_NIGHT("Good Night");
+
+ private final String literal;
+
+ private Greeting(final String literal) {
+ this.literal = literal;
+ }
+
+ public String getLiteral() {
+ return literal;
+ }
+
+}
\ No newline at end of file
diff --git a/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/User.java b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/User.java
new file mode 100644
index 0000000000..8e45487497
--- /dev/null
+++ b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/model/User.java
@@ -0,0 +1,14 @@
+package com.baeldung.openltablets.model;
+
+public class User {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/IRule.java b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/IRule.java
new file mode 100644
index 0000000000..857a6433ef
--- /dev/null
+++ b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/IRule.java
@@ -0,0 +1,7 @@
+package com.baeldung.openltablets.rules;
+
+import com.baeldung.openltablets.model.Case;
+
+public interface IRule {
+ void helloUser(final Case aCase, final Response response);
+}
\ No newline at end of file
diff --git a/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/Main.java b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/Main.java
new file mode 100644
index 0000000000..34f5c48ed1
--- /dev/null
+++ b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/Main.java
@@ -0,0 +1,31 @@
+package com.baeldung.openltablets.rules;
+
+
+import java.time.LocalDateTime;
+
+import org.openl.rules.runtime.RulesEngineFactory;
+import org.openl.runtime.EngineFactory;
+
+import com.baeldung.openltablets.model.Case;
+import com.baeldung.openltablets.model.User;
+
+public class Main {
+ private IRule instance;
+
+ public static void main(String[] args) {
+ Main rules = new Main();
+ User user = new User();
+ user.setName("Donald Duck");
+ Case aCase = new Case();
+ aCase.setUser(user);
+ aCase.setHourOfDay(23);
+ rules.process(aCase);
+ }
+
+ public void process(Case aCase) {
+ final EngineFactory engineFactory = new RulesEngineFactory(getClass().getClassLoader()
+ .getResource("openltablets/HelloUser.xls"), IRule.class);
+ instance = engineFactory.newEngineInstance();
+ instance.helloUser(aCase, new Response());
+ }
+}
diff --git a/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/Response.java b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/Response.java
new file mode 100644
index 0000000000..27fa634866
--- /dev/null
+++ b/rule-engines/openl-tablets/src/main/java/com/baeldung/openltablets/rules/Response.java
@@ -0,0 +1,24 @@
+package com.baeldung.openltablets.rules;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Response {
+ private String result;
+ private Map map = new HashMap<>();
+
+ public Response() { }
+
+ public String getResult() {
+ return result;
+ }
+
+ public void setResult(final String s) {
+ result = s;
+ }
+
+ public Map getMap() {
+ return map;
+ }
+
+}
diff --git a/rule-engines/openl-tablets/src/main/resources/openltablets/HelloUser.xls b/rule-engines/openl-tablets/src/main/resources/openltablets/HelloUser.xls
new file mode 100644
index 0000000000..1e85d0ce2d
Binary files /dev/null and b/rule-engines/openl-tablets/src/main/resources/openltablets/HelloUser.xls differ
diff --git a/rule-engines/rulebook/pom.xml b/rule-engines/rulebook/pom.xml
new file mode 100644
index 0000000000..711bee8c91
--- /dev/null
+++ b/rule-engines/rulebook/pom.xml
@@ -0,0 +1,24 @@
+
+ 4.0.0
+
+ com.baeldung.rulebook
+ rulebook
+ 1.0
+
+ rulebook
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ com.deliveredtechnologies
+ rulebook-core
+ 0.6.2
+
+
+
\ No newline at end of file
diff --git a/rule-engines/rulebook/src/main/java/com/baeldung/rulebook/HelloWorldRule.java b/rule-engines/rulebook/src/main/java/com/baeldung/rulebook/HelloWorldRule.java
new file mode 100644
index 0000000000..c09772a3c6
--- /dev/null
+++ b/rule-engines/rulebook/src/main/java/com/baeldung/rulebook/HelloWorldRule.java
@@ -0,0 +1,17 @@
+package com.baeldung.rulebook;
+
+import com.deliveredtechnologies.rulebook.lang.RuleBookBuilder;
+import com.deliveredtechnologies.rulebook.model.RuleBook;
+
+public class HelloWorldRule {
+ public RuleBook
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/User.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/User.java
new file mode 100644
index 0000000000..726fa53b02
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/User.java
@@ -0,0 +1,55 @@
+package com.baeldung.ldap.data.repository;
+
+import javax.naming.Name;
+
+import org.springframework.ldap.odm.annotations.Attribute;
+import org.springframework.ldap.odm.annotations.Entry;
+import org.springframework.ldap.odm.annotations.Id;
+
+@Entry(base = "ou=users", objectClasses = { "person", "inetOrgPerson", "top" })
+public class User {
+
+ @Id
+ private Name id;
+
+ private @Attribute(name = "cn") String username;
+ private @Attribute(name = "sn") String password;
+
+ public User() {
+ }
+
+ public User(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public Name getId() {
+ return id;
+ }
+
+ public void setId(Name id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return username;
+ }
+
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/UserRepository.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/UserRepository.java
new file mode 100644
index 0000000000..12dc0f7f14
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/repository/UserRepository.java
@@ -0,0 +1,17 @@
+package com.baeldung.ldap.data.repository;
+
+import java.util.List;
+
+import org.springframework.data.ldap.repository.LdapRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserRepository extends LdapRepository {
+
+ User findByUsername(String username);
+
+ User findByUsernameAndPassword(String username, String password);
+
+ List findByUsernameLikeIgnoreCase(String username);
+
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/service/LdapClient.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/LdapClient.java
new file mode 100644
index 0000000000..1b04edb35b
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/LdapClient.java
@@ -0,0 +1,87 @@
+package com.baeldung.ldap.data.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.ContextSource;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.support.LdapNameBuilder;
+
+import javax.naming.Name;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.List;
+
+public class LdapClient {
+
+ @Autowired
+ private Environment env;
+
+ @Autowired
+ private ContextSource contextSource;
+
+ @Autowired
+ private LdapTemplate ldapTemplate;
+
+ public void authenticate(final String username, final String password) {
+ contextSource.getContext("cn=" + username + ",ou=users," + env.getRequiredProperty("ldap.partitionSuffix"), password);
+ }
+
+ public List search(final String username) {
+ return ldapTemplate.search(
+ "ou=users",
+ "cn=" + username,
+ (AttributesMapper) attrs -> (String) attrs
+ .get("cn")
+ .get());
+ }
+
+ public void create(final String username, final String password) {
+ Name dn = LdapNameBuilder
+ .newInstance()
+ .add("ou", "users")
+ .add("cn", username)
+ .build();
+ DirContextAdapter context = new DirContextAdapter(dn);
+
+ context.setAttributeValues("objectclass", new String[]{"top", "person", "organizationalPerson", "inetOrgPerson"});
+ context.setAttributeValue("cn", username);
+ context.setAttributeValue("sn", username);
+ context.setAttributeValue("userPassword", digestSHA(password));
+
+ ldapTemplate.bind(context);
+ }
+
+ public void modify(final String username, final String password) {
+ Name dn = LdapNameBuilder
+ .newInstance()
+ .add("ou", "users")
+ .add("cn", username)
+ .build();
+ DirContextOperations context = ldapTemplate.lookupContext(dn);
+
+ context.setAttributeValues("objectclass", new String[]{"top", "person", "organizationalPerson", "inetOrgPerson"});
+ context.setAttributeValue("cn", username);
+ context.setAttributeValue("sn", username);
+ context.setAttributeValue("userPassword", digestSHA(password));
+
+ ldapTemplate.modifyAttributes(context);
+ }
+
+ private String digestSHA(final String password) {
+ String base64;
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA");
+ digest.update(password.getBytes());
+ base64 = Base64
+ .getEncoder()
+ .encodeToString(digest.digest());
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ return "{SHA}" + base64;
+ }
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/data/service/UserService.java b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/UserService.java
new file mode 100644
index 0000000000..54954e3c9d
--- /dev/null
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/data/service/UserService.java
@@ -0,0 +1,63 @@
+package com.baeldung.ldap.data.service;
+
+import com.baeldung.ldap.data.repository.User;
+import com.baeldung.ldap.data.repository.UserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ldap.support.LdapUtils;
+import org.springframework.stereotype.Service;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class UserService {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ public Boolean authenticate(final String username, final String password) {
+ User user = userRepository.findByUsernameAndPassword(username, password);
+ return user != null;
+ }
+
+ public List search(final String username) {
+ List userList = userRepository.findByUsernameLikeIgnoreCase(username);
+ if (userList == null) {
+ return Collections.emptyList();
+ }
+
+ return userList.stream()
+ .map(User::getUsername)
+ .collect(Collectors.toList());
+ }
+
+ public void create(final String username, final String password) {
+ User newUser = new User(username,digestSHA(password));
+ newUser.setId(LdapUtils.emptyLdapName());
+ userRepository.save(newUser);
+
+ }
+
+ public void modify(final String username, final String password) {
+ User user = userRepository.findByUsername(username);
+ user.setPassword(password);
+ userRepository.save(user);
+ }
+
+ private String digestSHA(final String password) {
+ String base64;
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA");
+ digest.update(password.getBytes());
+ base64 = Base64.getEncoder()
+ .encodeToString(digest.digest());
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ return "{SHA}" + base64;
+ }
+}
diff --git a/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java b/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java
index 8572e5d1be..fb3000b2bd 100644
--- a/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java
+++ b/spring-ldap/src/main/java/com/baeldung/ldap/javaconfig/AppConfig.java
@@ -1,5 +1,6 @@
package com.baeldung.ldap.javaconfig;
+import com.baeldung.ldap.client.LdapClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@@ -7,15 +8,15 @@ 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.ldap.repository.config.EnableLdapRepositories;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
-import com.baeldung.ldap.client.LdapClient;
-
@Configuration
@PropertySource("classpath:application.properties")
-@ComponentScan(basePackages = { "com.baeldung.ldap.*" })
+@ComponentScan(basePackages = {"com.baeldung.ldap.*"})
@Profile("default")
+@EnableLdapRepositories(basePackages = "com.baeldung.ldap.**")
public class AppConfig {
@Autowired
diff --git a/spring-ldap/src/main/resources/logback.xml b/spring-ldap/src/main/resources/logback.xml
index ec0dc2469a..32b78577ee 100644
--- a/spring-ldap/src/main/resources/logback.xml
+++ b/spring-ldap/src/main/resources/logback.xml
@@ -7,13 +7,13 @@
-
-
+
+
-
+
-
+
\ No newline at end of file
diff --git a/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapClientLiveTest.java b/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapClientLiveTest.java
index b65588dc38..f5b74d64c6 100644
--- a/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapClientLiveTest.java
+++ b/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapClientLiveTest.java
@@ -1,7 +1,6 @@
package com.baeldung.ldap.client;
-import java.util.List;
-
+import com.baeldung.ldap.javaconfig.TestConfig;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
@@ -13,11 +12,11 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
-import com.baeldung.ldap.javaconfig.TestConfig;
+import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("testlive")
-@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class)
+@ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class)
public class LdapClientLiveTest {
private static final String USER2 = "TEST02";
diff --git a/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapDataRepositoryTest.java b/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapDataRepositoryTest.java
new file mode 100644
index 0000000000..9f38af9263
--- /dev/null
+++ b/spring-ldap/src/test/java/com/baeldung/ldap/client/LdapDataRepositoryTest.java
@@ -0,0 +1,67 @@
+package com.baeldung.ldap.client;
+
+import com.baeldung.ldap.data.service.UserService;
+import com.baeldung.ldap.javaconfig.TestConfig;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ActiveProfiles("testlive")
+@ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class)
+public class LdapDataRepositoryTest {
+
+ private static final String USER2 = "TEST02";
+ private static final String USER3 = "TEST03";
+ private static final String USER4 = "TEST04";
+
+ private static final String USER2_PWD = "TEST02";
+ private static final String USER3_PWD = "TEST03";
+ private static final String USER4_PWD = "TEST04";
+
+ private static final String SEARCH_STRING = "TEST*";
+
+ @Autowired
+ private UserService userService;
+
+ @Test
+ public void givenLdapClient_whenCorrectCredentials_thenSuccessfulLogin() {
+ Boolean isValid = userService.authenticate(USER3, USER3_PWD);
+ assertEquals(true, isValid);
+ }
+
+ @Test
+ public void givenLdapClient_whenIncorrectCredentials_thenFailedLogin() {
+ Boolean isValid = userService.authenticate(USER3, USER2_PWD);
+ assertEquals(false, isValid);
+ }
+
+ @Test
+ public void givenLdapClient_whenCorrectSearchFilter_thenEntriesReturned() {
+ List userList = userService.search(SEARCH_STRING);
+ assertThat(userList, Matchers.containsInAnyOrder(USER2, USER3));
+ }
+
+ @Test
+ public void givenLdapClientNotExists_whenDataProvided_thenNewUserCreated() {
+ userService.create(USER4, USER4_PWD);
+ userService.authenticate(USER4, USER4_PWD);
+ }
+
+ @Test
+ public void givenLdapClientExists_whenDataProvided_thenExistingUserModified() {
+ userService.modify(USER2, USER3_PWD);
+ userService.authenticate(USER2, USER3_PWD);
+ }
+
+}
diff --git a/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java b/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java
index e2968e977c..c6293982da 100644
--- a/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java
+++ b/spring-ldap/src/test/java/com/baeldung/ldap/javaconfig/TestConfig.java
@@ -1,5 +1,6 @@
package com.baeldung.ldap.javaconfig;
+import com.baeldung.ldap.client.LdapClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@@ -8,15 +9,15 @@ import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
+import org.springframework.data.ldap.repository.config.EnableLdapRepositories;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.test.TestContextSourceFactoryBean;
-import com.baeldung.ldap.client.LdapClient;
-
@Configuration
@PropertySource("classpath:test_application.properties")
-@ComponentScan(basePackages = { "com.baeldung.ldap.*" })
+@ComponentScan(basePackages = {"com.baeldung.ldap.*"})
+@EnableLdapRepositories(basePackages = "com.baeldung.ldap.**")
@Profile("testlive")
public class TestConfig {
@Autowired
diff --git a/spring-mvc-email/pom.xml b/spring-mvc-email/pom.xml
index c40abdb4bf..9228054878 100644
--- a/spring-mvc-email/pom.xml
+++ b/spring-mvc-email/pom.xml
@@ -21,16 +21,17 @@
org.springframework.boot
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
org.springframework.boot
spring-boot-starter-mail
-
+
-
- org.apache.tomcat.embed
- tomcat-embed-jasper
-
javax.servlet
jstl
diff --git a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java b/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java
index f146ee1d04..bc5d6b3151 100644
--- a/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java
+++ b/spring-mvc-email/src/main/java/com/baeldung/spring/Application.java
@@ -2,10 +2,11 @@ package com.baeldung.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
@SpringBootApplication
-public class Application {
+public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
diff --git a/spring-mvc-kotlin/pom.xml b/spring-mvc-kotlin/pom.xml
new file mode 100644
index 0000000000..087f02fc68
--- /dev/null
+++ b/spring-mvc-kotlin/pom.xml
@@ -0,0 +1,79 @@
+
+
+ 4.0.0
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+ spring-mvc-kotlin
+ 0.1-SNAPSHOT
+
+ spring-mvc-kotlin
+
+ war
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jre8
+ 1.1.4
+
+
+ org.jetbrains.kotlin
+ kotlin-reflect
+ 1.1.4
+
+
+
+ org.springframework
+ spring-web
+ 4.3.10.RELEASE
+
+
+ org.springframework
+ spring-webmvc
+ 4.3.10.RELEASE
+
+
+ javax.servlet
+ jstl
+ 1.2
+
+
+
+
+ ${project.basedir}/src/main/kotlin
+ ${project.basedir}/src/test/kotlin
+
+
+ kotlin-maven-plugin
+ org.jetbrains.kotlin
+ 1.1.4
+
+
+
+ compile
+ compile
+
+ compile
+
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mvc/ApplicationWebConfig.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mvc/ApplicationWebConfig.kt
new file mode 100644
index 0000000000..4907e46efb
--- /dev/null
+++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mvc/ApplicationWebConfig.kt
@@ -0,0 +1,37 @@
+package com.baeldung.kotlin.mvc
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.web.servlet.ViewResolver
+import org.springframework.web.servlet.config.annotation.EnableWebMvc
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
+import org.springframework.web.servlet.view.InternalResourceViewResolver
+import org.springframework.web.servlet.view.JstlView
+
+
+
+
+
+@EnableWebMvc
+@Configuration
+open class ApplicationWebConfig: WebMvcConfigurerAdapter() {
+
+ override fun addViewControllers(registry: ViewControllerRegistry?) {
+ super.addViewControllers(registry)
+
+ registry!!.addViewController("/welcome.html")
+ }
+
+ @Bean
+ open fun viewResolver(): ViewResolver {
+ val bean = InternalResourceViewResolver()
+
+ bean.setViewClass(JstlView::class.java)
+ bean.setPrefix("/WEB-INF/view/")
+ bean.setSuffix(".jsp")
+
+ return bean
+ }
+
+}
\ No newline at end of file
diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mvc/ApplicationWebInitializer.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mvc/ApplicationWebInitializer.kt
new file mode 100644
index 0000000000..a4d1614271
--- /dev/null
+++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/mvc/ApplicationWebInitializer.kt
@@ -0,0 +1,19 @@
+package com.baeldung.kotlin.mvc
+
+import com.baeldung.kotlin.mvc.ApplicationWebConfig
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
+
+class ApplicationWebInitializer: AbstractAnnotationConfigDispatcherServletInitializer() {
+
+ override fun getRootConfigClasses(): Array>? {
+ return null
+ }
+
+ override fun getServletMappings(): Array {
+ return arrayOf("/")
+ }
+
+ override fun getServletConfigClasses(): Array> {
+ return arrayOf(ApplicationWebConfig::class.java)
+ }
+}
\ No newline at end of file
diff --git a/spring-mvc-kotlin/src/main/webapp/WEB-INF/spring-web-config.xml b/spring-mvc-kotlin/src/main/webapp/WEB-INF/spring-web-config.xml
new file mode 100644
index 0000000000..ffe83a66fa
--- /dev/null
+++ b/spring-mvc-kotlin/src/main/webapp/WEB-INF/spring-web-config.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-kotlin/src/main/webapp/WEB-INF/view/welcome.jsp b/spring-mvc-kotlin/src/main/webapp/WEB-INF/view/welcome.jsp
new file mode 100644
index 0000000000..bdb6716889
--- /dev/null
+++ b/spring-mvc-kotlin/src/main/webapp/WEB-INF/view/welcome.jsp
@@ -0,0 +1,7 @@
+
+ Welcome
+
+
+ This is the body of the welcome view 2
+
+
\ No newline at end of file
diff --git a/spring-mvc-kotlin/src/main/webapp/WEB-INF/web.xml b/spring-mvc-kotlin/src/main/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000000..cbee6a1b11
--- /dev/null
+++ b/spring-mvc-kotlin/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+
+
+ Spring Kotlin MVC Application
+
+
+ spring-web-mvc
+ org.springframework.web.servlet.DispatcherServlet
+ 1
+
+ contextConfigLocation
+ /WEB-INF/spring-web-config.xml
+
+
+
+
+ spring-web-mvc
+ /
+
+
+
\ No newline at end of file
diff --git a/spring-rest/README.md b/spring-rest/README.md
index 66c893e45f..2cea315188 100644
--- a/spring-rest/README.md
+++ b/spring-rest/README.md
@@ -15,3 +15,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [A Custom Media Type for a Spring REST API](http://www.baeldung.com/spring-rest-custom-media-type)
- [HTTP PUT vs HTTP PATCH in a REST API](http://www.baeldung.com/http-put-patch-difference-spring)
- [Exploring the Spring Boot TestRestTemplate](http://www.baeldung.com/spring-boot-testresttemplate)
+- [Spring – Log Incoming Requests](http://www.baeldung.com/spring-http-logging)
diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java b/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java
index 472c0c8bf5..59868593a3 100644
--- a/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java
+++ b/spring-rest/src/main/java/org/baeldung/web/controller/redirect/RedirectController.java
@@ -1,11 +1,15 @@
package org.baeldung.web.controller.redirect;
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.View;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
@@ -49,4 +53,16 @@ public class RedirectController {
model.addAttribute("redirectionAttribute", flashAttribute);
return new ModelAndView("redirection", model);
}
+
+ @RequestMapping(value = "/redirectPostToPost", method = RequestMethod.POST)
+ public ModelAndView redirectPostToPost(HttpServletRequest request) {
+ request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT);
+ return new ModelAndView("redirect:/redirectedPostToPost");
+ }
+
+ @RequestMapping(value = "/redirectedPostToPost", method = RequestMethod.POST)
+ public ModelAndView redirectedPostToPost() {
+ return new ModelAndView("redirection");
+ }
+
}
\ No newline at end of file
diff --git a/spring-security-mvc-ldap/pom.xml b/spring-security-mvc-ldap/pom.xml
index f2b6b766eb..e6452ea70b 100644
--- a/spring-security-mvc-ldap/pom.xml
+++ b/spring-security-mvc-ldap/pom.xml
@@ -57,7 +57,7 @@
- 1.5.7
+ 1.5.5
diff --git a/spring-security-mvc-ldap/src/main/java/org/baeldung/SampleLDAPApplication.java b/spring-security-mvc-ldap/src/main/java/org/baeldung/SampleLDAPApplication.java
index 4bcb255046..5936aa30ef 100644
--- a/spring-security-mvc-ldap/src/main/java/org/baeldung/SampleLDAPApplication.java
+++ b/spring-security-mvc-ldap/src/main/java/org/baeldung/SampleLDAPApplication.java
@@ -1,8 +1,9 @@
package org.baeldung;
import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.context.annotation.ComponentScan;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@@ -11,17 +12,22 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
* class to run up a Jetty Server (on http://localhost:8080)
*
*/
-@EnableAutoConfiguration
-@ComponentScan("org.baeldung")
-public class SampleLDAPApplication extends WebMvcConfigurerAdapter {
+@SpringBootApplication
+public class SampleLDAPApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SampleLDAPApplication.class, args);
}
- @Override
- public void addViewControllers(ViewControllerRegistry registry) {
- registry.addViewController("/login").setViewName("login");
+ @Bean
+ public WebMvcConfigurerAdapter adapter() {
+ return new WebMvcConfigurerAdapter() {
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/login")
+ .setViewName("login");
+ }
+ };
}
}
\ No newline at end of file
diff --git a/spring-security-rest-custom/pom.xml b/spring-security-rest-custom/pom.xml
index c329bd1cb8..77a58a56d8 100644
--- a/spring-security-rest-custom/pom.xml
+++ b/spring-security-rest-custom/pom.xml
@@ -33,12 +33,6 @@
org.springframework
spring-core
-
-
- commons-logging
- commons-logging
-
-
org.springframework
@@ -79,6 +73,12 @@
spring-oxm
+
+ commons-logging
+ commons-logging
+ ${commons-logging.version}
+
+
@@ -105,24 +105,11 @@
org.apache.httpcomponents
httpcore
- ${httpcore.version}
-
-
- commons-logging
- commons-logging
-
-
org.apache.httpcomponents
httpclient
-
-
- commons-logging
- commons-logging
-
-
@@ -213,7 +200,7 @@
19.0
3.5
-
+ 1.2
4.4.5
4.5.2
diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java
index 5ef699d264..c0ad5eb690 100644
--- a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java
+++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java
@@ -3,24 +3,14 @@ package org.baeldung.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.context.request.RequestContextListener;
@EnableOAuth2Sso
@SpringBootApplication
-public class UiApplication extends WebSecurityConfigurerAdapter {
+public class UiApplication extends SpringBootServletInitializer {
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.antMatcher("/**")
- .authorizeRequests()
- .antMatchers("/", "/login**")
- .permitAll()
- .anyRequest()
- .authenticated();
- }
@Bean
public RequestContextListener requestContextListener() {
diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java
new file mode 100644
index 0000000000..5dbe9ada34
--- /dev/null
+++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiSecurityConfig.java
@@ -0,0 +1,20 @@
+package org.baeldung.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ http.antMatcher("/**")
+ .authorizeRequests()
+ .antMatchers("/", "/login**")
+ .permitAll()
+ .anyRequest()
+ .authenticated();
+ }
+
+}
diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java
index 5ef699d264..e186046e83 100644
--- a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java
+++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java
@@ -2,25 +2,13 @@ package org.baeldung.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.context.request.RequestContextListener;
-@EnableOAuth2Sso
-@SpringBootApplication
-public class UiApplication extends WebSecurityConfigurerAdapter {
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.antMatcher("/**")
- .authorizeRequests()
- .antMatchers("/", "/login**")
- .permitAll()
- .anyRequest()
- .authenticated();
- }
+@SpringBootApplication
+public class UiApplication extends SpringBootServletInitializer {
@Bean
public RequestContextListener requestContextListener() {
diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java
new file mode 100644
index 0000000000..f9119e20f5
--- /dev/null
+++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiSecurityConfig.java
@@ -0,0 +1,22 @@
+package org.baeldung.config;
+
+import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@EnableOAuth2Sso
+@Configuration
+public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ http.antMatcher("/**")
+ .authorizeRequests()
+ .antMatchers("/", "/login**")
+ .permitAll()
+ .anyRequest()
+ .authenticated();
+ }
+
+}
diff --git a/spring-zuul/spring-zuul-ui/src/main/java/org/baeldung/config/UiApplication.java b/spring-zuul/spring-zuul-ui/src/main/java/org/baeldung/config/UiApplication.java
index 625e5439ee..b8eda25960 100644
--- a/spring-zuul/spring-zuul-ui/src/main/java/org/baeldung/config/UiApplication.java
+++ b/spring-zuul/spring-zuul-ui/src/main/java/org/baeldung/config/UiApplication.java
@@ -2,11 +2,12 @@ package org.baeldung.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@SpringBootApplication
-public class UiApplication {
+public class UiApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(UiApplication.class, args);
diff --git a/testing/README.md b/testing/README.md
index 6338a52f3d..a691737e4f 100644
--- a/testing/README.md
+++ b/testing/README.md
@@ -12,3 +12,4 @@
- [Testing with Google Truth](http://www.baeldung.com/google-truth)
- [Testing with JGoTesting](http://www.baeldung.com/jgotesting)
- [Introduction to JUnitParams](http://www.baeldung.com/junit-params)
+- [Cucumber Java 8 Support](http://www.baeldung.com/cucumber-java-8-support)
diff --git a/undertow/pom.xml b/undertow/pom.xml
new file mode 100644
index 0000000000..33bac57178
--- /dev/null
+++ b/undertow/pom.xml
@@ -0,0 +1,53 @@
+
+ 4.0.0
+ com.baeldung.undertow
+ undertow
+ jar
+ 1.0-SNAPSHOT
+ undertow
+ http://maven.apache.org
+
+
+ 1.8
+ 1.8
+
+
+
+
+ io.undertow
+ undertow-servlet
+ 1.4.18.Final
+
+
+
+
+ ${project.artifactId}
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+ package
+
+ shade
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ com.baeldung.undertow.SimpleServer
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/undertow/src/main/java/com/baeldung/undertow/SimpleServer.java b/undertow/src/main/java/com/baeldung/undertow/SimpleServer.java
new file mode 100644
index 0000000000..7f869746be
--- /dev/null
+++ b/undertow/src/main/java/com/baeldung/undertow/SimpleServer.java
@@ -0,0 +1,16 @@
+package com.baeldung.undertow;
+
+import io.undertow.Undertow;
+import io.undertow.util.Headers;
+
+public class SimpleServer {
+
+ public static void main(String[] args) {
+ Undertow server = Undertow.builder().addHttpListener(8080, "localhost").setHandler(exchange -> {
+ exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
+ exchange.getResponseSender().send("Hello Baeldung");
+ }).build();
+ server.start();
+ }
+
+}
diff --git a/undertow/src/main/java/com/baeldung/undertow/ftp/FileServer.java b/undertow/src/main/java/com/baeldung/undertow/ftp/FileServer.java
new file mode 100644
index 0000000000..f5cdb827a6
--- /dev/null
+++ b/undertow/src/main/java/com/baeldung/undertow/ftp/FileServer.java
@@ -0,0 +1,20 @@
+package com.baeldung.undertow.ftp;
+
+import io.undertow.Undertow;
+import io.undertow.server.handlers.resource.PathResourceManager;
+
+import java.nio.file.Paths;
+
+import static io.undertow.Handlers.resource;
+
+public class FileServer {
+
+ public static void main(String[] args) {
+ Undertow server = Undertow.builder().addHttpListener(8080, "localhost")
+ .setHandler(resource(new PathResourceManager(Paths.get(System.getProperty("user.home")), 100))
+ .setDirectoryListingEnabled(true))
+ .build();
+ server.start();
+ }
+
+}
diff --git a/undertow/src/main/java/com/baeldung/undertow/secure/CustomIdentityManager.java b/undertow/src/main/java/com/baeldung/undertow/secure/CustomIdentityManager.java
new file mode 100644
index 0000000000..491941261a
--- /dev/null
+++ b/undertow/src/main/java/com/baeldung/undertow/secure/CustomIdentityManager.java
@@ -0,0 +1,73 @@
+package com.baeldung.undertow.secure;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import io.undertow.security.idm.Account;
+import io.undertow.security.idm.Credential;
+import io.undertow.security.idm.IdentityManager;
+import io.undertow.security.idm.PasswordCredential;
+
+public class CustomIdentityManager implements IdentityManager {
+
+ private final Map users;
+
+ CustomIdentityManager(final Map users) {
+ this.users = users;
+ }
+
+ @Override
+ public Account verify(Account account) {
+ return account;
+ }
+
+ @Override
+ public Account verify(Credential credential) {
+ return null;
+ }
+
+ @Override
+ public Account verify(String id, Credential credential) {
+ Account account = getAccount(id);
+ if (account != null && verifyCredential(account, credential)) {
+ return account;
+ }
+ return null;
+ }
+
+ private boolean verifyCredential(Account account, Credential credential) {
+ if (credential instanceof PasswordCredential) {
+ char[] password = ((PasswordCredential) credential).getPassword();
+ char[] expectedPassword = users.get(account.getPrincipal().getName());
+
+ return Arrays.equals(password, expectedPassword);
+ }
+ return false;
+ }
+
+ private Account getAccount(final String id) {
+ if (users.containsKey(id)) {
+ return new Account() {
+
+ private static final long serialVersionUID = 1L;
+
+ private final Principal principal = () -> id;
+
+ @Override
+ public Principal getPrincipal() {
+ return principal;
+ }
+
+ @Override
+ public Set getRoles() {
+ return Collections.emptySet();
+ }
+ };
+ }
+ return null;
+ }
+
+}
diff --git a/undertow/src/main/java/com/baeldung/undertow/secure/SecureServer.java b/undertow/src/main/java/com/baeldung/undertow/secure/SecureServer.java
new file mode 100644
index 0000000000..6532c3ed7c
--- /dev/null
+++ b/undertow/src/main/java/com/baeldung/undertow/secure/SecureServer.java
@@ -0,0 +1,54 @@
+package com.baeldung.undertow.secure;
+
+import io.undertow.Undertow;
+import io.undertow.io.IoCallback;
+import io.undertow.security.api.AuthenticationMechanism;
+import io.undertow.security.api.AuthenticationMode;
+import io.undertow.security.api.SecurityContext;
+import io.undertow.security.handlers.AuthenticationCallHandler;
+import io.undertow.security.handlers.AuthenticationConstraintHandler;
+import io.undertow.security.handlers.AuthenticationMechanismsHandler;
+import io.undertow.security.handlers.SecurityInitialHandler;
+import io.undertow.security.idm.IdentityManager;
+import io.undertow.security.impl.BasicAuthenticationMechanism;
+import io.undertow.server.HttpHandler;
+import io.undertow.server.HttpServerExchange;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SecureServer {
+
+ public static void main(String[] args) {
+ final Map users = new HashMap<>(2);
+ users.put("root", "password".toCharArray());
+ users.put("admin", "password".toCharArray());
+
+ final IdentityManager idm = new CustomIdentityManager(users);
+
+ Undertow server = Undertow.builder()
+ .addHttpListener(8080, "localhost")
+ .setHandler(addSecurity(SecureServer::setExchange, idm)).build();
+
+ server.start();
+ }
+
+ private static void setExchange(HttpServerExchange exchange) {
+ final SecurityContext context = exchange.getSecurityContext();
+ exchange.getResponseSender().send("Hello " + context.getAuthenticatedAccount().getPrincipal().getName(), IoCallback.END_EXCHANGE);
+ }
+
+ private static HttpHandler addSecurity(final HttpHandler toWrap, final IdentityManager identityManager) {
+ HttpHandler handler = toWrap;
+ handler = new AuthenticationCallHandler(handler);
+ handler = new AuthenticationConstraintHandler(handler);
+ final List mechanisms = Collections
+ .singletonList(new BasicAuthenticationMechanism("Baeldung_Realm"));
+ handler = new AuthenticationMechanismsHandler(handler, mechanisms);
+ handler = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, identityManager, handler);
+ return handler;
+ }
+
+}
diff --git a/undertow/src/main/java/com/baeldung/undertow/socket/SocketServer.java b/undertow/src/main/java/com/baeldung/undertow/socket/SocketServer.java
new file mode 100644
index 0000000000..295586e16f
--- /dev/null
+++ b/undertow/src/main/java/com/baeldung/undertow/socket/SocketServer.java
@@ -0,0 +1,40 @@
+package com.baeldung.undertow.socket;
+
+import io.undertow.Undertow;
+import io.undertow.server.handlers.resource.ClassPathResourceManager;
+import io.undertow.websockets.core.AbstractReceiveListener;
+import io.undertow.websockets.core.BufferedTextMessage;
+import io.undertow.websockets.core.WebSocketChannel;
+import io.undertow.websockets.core.WebSockets;
+
+import static io.undertow.Handlers.path;
+import static io.undertow.Handlers.resource;
+import static io.undertow.Handlers.websocket;
+
+public class SocketServer {
+
+ public static void main(String[] args) {
+ Undertow server = Undertow.builder().addHttpListener(8080, "localhost")
+ .setHandler(path().addPrefixPath("/baeldungApp", websocket((exchange, channel) -> {
+ channel.getReceiveSetter().set(getListener());
+ channel.resumeReceives();
+ })).addPrefixPath("/", resource(new ClassPathResourceManager(SocketServer.class.getClassLoader(),
+ SocketServer.class.getPackage())).addWelcomeFiles("index.html")))
+ .build();
+
+ server.start();
+ }
+
+ private static AbstractReceiveListener getListener() {
+ return new AbstractReceiveListener() {
+ @Override
+ protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) {
+ final String messageData = message.getData();
+ for (WebSocketChannel session : channel.getPeerConnections()) {
+ WebSockets.sendText(messageData, session, null);
+ }
+ }
+ };
+ }
+
+}
diff --git a/vavr/README.md b/vavr/README.md
index c4155c2680..d7816f3f9f 100644
--- a/vavr/README.md
+++ b/vavr/README.md
@@ -5,3 +5,4 @@
- [Property Testing Example With Vavr](http://www.baeldung.com/javaslang-property-testing)
- [Exceptions in Lambda Expression Using Vavr](http://www.baeldung.com/exceptions-using-vavr)
- [Vavr (ex-Javaslang) Support in Spring Data](http://www.baeldung.com/spring-vavr)
+