diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000..9c5cdb8f2d
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "testgitrepo"]
+ path = testgitrepo
+ url = /home/prd/Development/projects/idea/tutorials/spring-boot/src/main/resources/testgitrepo/
diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml
new file mode 100644
index 0000000000..6d07394b87
--- /dev/null
+++ b/annotations/annotation-processing/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ annotations
+ ../
+
+
+ annotation-processing
+
+
+ 1.0-rc2
+ 3.5.1
+
+
+
+
+
+ com.google.auto.service
+ auto-service
+ ${auto-service.version}
+ provided
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ 1.8
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java
new file mode 100644
index 0000000000..0883e108e7
--- /dev/null
+++ b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java
@@ -0,0 +1,132 @@
+package com.baeldung.annotation.processor;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+import com.google.auto.service.AutoService;
+
+@SupportedAnnotationTypes("com.baeldung.annotation.processor.BuilderProperty")
+@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@AutoService(Processor.class)
+public class BuilderProcessor extends AbstractProcessor {
+
+ @Override
+ public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ for (TypeElement annotation : annotations) {
+
+ Set extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
+
+ Map> annotatedMethods = annotatedElements.stream()
+ .collect(Collectors.partitioningBy(element ->
+ ((ExecutableType) element.asType()).getParameterTypes().size() == 1
+ && element.getSimpleName().toString().startsWith("set")));
+
+ List setters = annotatedMethods.get(true);
+ List otherMethods = annotatedMethods.get(false);
+
+ otherMethods.forEach(element ->
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
+ "@BuilderProperty must be applied to a setXxx method with a single argument", element));
+
+ if (setters.isEmpty()) {
+ continue;
+ }
+
+ String className = ((TypeElement) setters.get(0).getEnclosingElement()).getQualifiedName().toString();
+
+ Map setterMap = setters.stream().collect(Collectors.toMap(
+ setter -> setter.getSimpleName().toString(),
+ setter -> ((ExecutableType) setter.asType())
+ .getParameterTypes().get(0).toString()
+ ));
+
+ try {
+ writeBuilderFile(className, setterMap);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ return true;
+ }
+
+ private void writeBuilderFile(String className, Map setterMap) throws IOException {
+
+ String packageName = null;
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot > 0) {
+ packageName = className.substring(0, lastDot);
+ }
+
+ String simpleClassName = className.substring(lastDot + 1);
+ String builderClassName = className + "Builder";
+ String builderSimpleClassName = builderClassName.substring(lastDot + 1);
+
+ JavaFileObject builderFile = processingEnv.getFiler().createSourceFile(builderClassName);
+ try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
+
+ if (packageName != null) {
+ out.print("package ");
+ out.print(packageName);
+ out.println(";");
+ out.println();
+ }
+
+ out.print("public class ");
+ out.print(builderSimpleClassName);
+ out.println(" {");
+ out.println();
+
+ out.print(" private ");
+ out.print(simpleClassName);
+ out.print(" object = new ");
+ out.print(simpleClassName);
+ out.println("();");
+ out.println();
+
+ out.print(" public ");
+ out.print(simpleClassName);
+ out.println(" build() {");
+ out.println(" return object;");
+ out.println(" }");
+ out.println();
+
+ setterMap.entrySet().forEach(setter -> {
+ String methodName = setter.getKey();
+ String argumentType = setter.getValue();
+
+ out.print(" public ");
+ out.print(builderSimpleClassName);
+ out.print(" ");
+ out.print(methodName);
+
+ out.print("(");
+
+ out.print(argumentType);
+ out.println(" value) {");
+ out.print(" object.");
+ out.print(methodName);
+ out.println("(value);");
+ out.println(" return this;");
+ out.println(" }");
+ out.println();
+ });
+
+ out.println("}");
+
+ }
+ }
+
+}
diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java
new file mode 100644
index 0000000000..84fcc73850
--- /dev/null
+++ b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java
@@ -0,0 +1,8 @@
+package com.baeldung.annotation.processor;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface BuilderProperty {
+}
diff --git a/annotations/annotation-user/pom.xml b/annotations/annotation-user/pom.xml
new file mode 100644
index 0000000000..f76f691f93
--- /dev/null
+++ b/annotations/annotation-user/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+
+
+ annotations
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../
+
+
+ annotation-user
+
+
+
+
+ com.baeldung
+ annotation-processing
+ ${project.parent.version}
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.5.1
+
+
+ 1.8
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java b/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java
new file mode 100644
index 0000000000..23787ba4f4
--- /dev/null
+++ b/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java
@@ -0,0 +1,29 @@
+package com.baeldung.annotation;
+
+import com.baeldung.annotation.processor.BuilderProperty;
+
+public class Person {
+
+ private int age;
+
+ private String name;
+
+ public int getAge() {
+ return age;
+ }
+
+ @BuilderProperty
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @BuilderProperty
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java b/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java
new file mode 100644
index 0000000000..72f9ac8bc7
--- /dev/null
+++ b/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.annotation;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class PersonBuilderTest {
+
+ @Test
+ public void whenBuildPersonWithBuilder_thenObjectHasPropertyValues() {
+
+ Person person = new PersonBuilder()
+ .setAge(25)
+ .setName("John")
+ .build();
+
+ assertEquals(25, person.getAge());
+ assertEquals("John", person.getName());
+
+ }
+
+}
diff --git a/annotations/pom.xml b/annotations/pom.xml
new file mode 100644
index 0000000000..f691674cf1
--- /dev/null
+++ b/annotations/pom.xml
@@ -0,0 +1,20 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+ 4.0.0
+
+ annotations
+ pom
+
+
+ annotation-processing
+ annotation-user
+
+
+
\ No newline at end of file
diff --git a/autovalue-tutorial/pom.xml b/autovalue-tutorial/pom.xml
index 37d595dce1..d1f8e825fc 100644
--- a/autovalue-tutorial/pom.xml
+++ b/autovalue-tutorial/pom.xml
@@ -1,36 +1,37 @@
- 4.0.0
- com.baeldung
- autovalue-tutorial
- 1.0
- AutoValue
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.3
-
-
- 7
-
-
-
-
-
-
- com.google.auto.value
- auto-value
- 1.2
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ 4.0.0
+ com.baeldung
+ autovalue-tutorial
+ 1.0
+ AutoValue
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+
+ 7
+ false
+
+
+
+
+
+
+ com.google.auto.value
+ auto-value
+ 1.2
+
-
- junit
- junit
- 4.3
- test
-
+
+ junit
+ junit
+ 4.3
+ test
+
-
+
diff --git a/cdi/pom.xml b/cdi/pom.xml
new file mode 100644
index 0000000000..b771857938
--- /dev/null
+++ b/cdi/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ cdi
+ 1.0-SNAPSHOT
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+ org.aspectj
+ aspectjweaver
+ 1.8.9
+
+
+ org.jboss.weld.se
+ weld-se-core
+ 2.3.5.Final
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.springframework
+ spring-test
+ ${spring.version}
+ test
+
+
+
+
+
+ 4.3.1.RELEASE
+
+
+
\ No newline at end of file
diff --git a/cdi/src/main/java/com/baeldung/interceptor/Audited.java b/cdi/src/main/java/com/baeldung/interceptor/Audited.java
new file mode 100644
index 0000000000..3df4bef95e
--- /dev/null
+++ b/cdi/src/main/java/com/baeldung/interceptor/Audited.java
@@ -0,0 +1,14 @@
+package com.baeldung.interceptor;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.interceptor.InterceptorBinding;
+
+@InterceptorBinding
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Audited {
+}
diff --git a/cdi/src/main/java/com/baeldung/interceptor/AuditedInterceptor.java b/cdi/src/main/java/com/baeldung/interceptor/AuditedInterceptor.java
new file mode 100644
index 0000000000..c62d9a4127
--- /dev/null
+++ b/cdi/src/main/java/com/baeldung/interceptor/AuditedInterceptor.java
@@ -0,0 +1,20 @@
+package com.baeldung.interceptor;
+
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+
+@Audited
+@Interceptor
+public class AuditedInterceptor {
+ public static boolean calledBefore = false;
+ public static boolean calledAfter = false;
+
+ @AroundInvoke
+ public Object auditMethod(InvocationContext ctx) throws Exception {
+ calledBefore = true;
+ Object result = ctx.proceed();
+ calledAfter = true;
+ return result;
+ }
+}
diff --git a/cdi/src/main/java/com/baeldung/service/SuperService.java b/cdi/src/main/java/com/baeldung/service/SuperService.java
new file mode 100644
index 0000000000..e15f049342
--- /dev/null
+++ b/cdi/src/main/java/com/baeldung/service/SuperService.java
@@ -0,0 +1,10 @@
+package com.baeldung.service;
+
+import com.baeldung.interceptor.Audited;
+
+public class SuperService {
+ @Audited
+ public String deliverService(String uid) {
+ return uid;
+ }
+}
diff --git a/cdi/src/main/java/com/baeldung/spring/aspect/SpringTestAspect.java b/cdi/src/main/java/com/baeldung/spring/aspect/SpringTestAspect.java
new file mode 100644
index 0000000000..e48039706d
--- /dev/null
+++ b/cdi/src/main/java/com/baeldung/spring/aspect/SpringTestAspect.java
@@ -0,0 +1,23 @@
+package com.baeldung.spring.aspect;
+
+import java.util.List;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Autowired;
+
+@Aspect
+public class SpringTestAspect {
+ @Autowired
+ private List accumulator;
+
+ @Around("execution(* com.baeldung.spring.service.SpringSuperService.*(..))")
+ public Object auditMethod(ProceedingJoinPoint jp) throws Throwable {
+ String methodName = jp.getSignature().getName();
+ accumulator.add("Call to " + methodName);
+ Object obj = jp.proceed();
+ accumulator.add("Method called successfully: " + methodName);
+ return obj;
+ }
+}
diff --git a/cdi/src/main/java/com/baeldung/spring/configuration/AppConfig.java b/cdi/src/main/java/com/baeldung/spring/configuration/AppConfig.java
new file mode 100644
index 0000000000..b30c4a1326
--- /dev/null
+++ b/cdi/src/main/java/com/baeldung/spring/configuration/AppConfig.java
@@ -0,0 +1,30 @@
+package com.baeldung.spring.configuration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+import com.baeldung.spring.aspect.SpringTestAspect;
+import com.baeldung.spring.service.SpringSuperService;
+
+@Configuration
+@EnableAspectJAutoProxy
+public class AppConfig {
+ @Bean
+ public SpringSuperService springSuperService() {
+ return new SpringSuperService();
+ }
+
+ @Bean
+ public SpringTestAspect springTestAspect() {
+ return new SpringTestAspect();
+ }
+
+ @Bean
+ public List getAccumulator() {
+ return new ArrayList();
+ }
+}
diff --git a/cdi/src/main/java/com/baeldung/spring/service/SpringSuperService.java b/cdi/src/main/java/com/baeldung/spring/service/SpringSuperService.java
new file mode 100644
index 0000000000..082eb2e0f8
--- /dev/null
+++ b/cdi/src/main/java/com/baeldung/spring/service/SpringSuperService.java
@@ -0,0 +1,7 @@
+package com.baeldung.spring.service;
+
+public class SpringSuperService {
+ public String getInfoFromService(String code) {
+ return code;
+ }
+}
diff --git a/cdi/src/main/resources/META-INF/beans.xml b/cdi/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000000..d41b35e7d9
--- /dev/null
+++ b/cdi/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,8 @@
+
+
+ com.baeldung.interceptor.AuditedInterceptor
+
+
\ No newline at end of file
diff --git a/cdi/src/test/java/com/baeldung/test/TestInterceptor.java b/cdi/src/test/java/com/baeldung/test/TestInterceptor.java
new file mode 100644
index 0000000000..3529a796d2
--- /dev/null
+++ b/cdi/src/test/java/com/baeldung/test/TestInterceptor.java
@@ -0,0 +1,38 @@
+package com.baeldung.test;
+
+import org.jboss.weld.environment.se.Weld;
+import org.jboss.weld.environment.se.WeldContainer;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.interceptor.AuditedInterceptor;
+import com.baeldung.service.SuperService;
+
+public class TestInterceptor {
+ Weld weld;
+ WeldContainer container;
+
+ @Before
+ public void init() {
+ weld = new Weld();
+ container = weld.initialize();
+ }
+
+ @After
+ public void shutdown() {
+ weld.shutdown();
+ }
+
+ @Test
+ public void givenTheService_whenMethodAndInterceptorExecuted_thenOK() {
+ SuperService superService = container.select(SuperService.class).get();
+ String code = "123456";
+ superService.deliverService(code);
+
+ Assert.assertTrue(AuditedInterceptor.calledBefore);
+ Assert.assertTrue(AuditedInterceptor.calledAfter);
+ }
+
+}
diff --git a/cdi/src/test/java/com/baeldung/test/TestSpringInterceptor.java b/cdi/src/test/java/com/baeldung/test/TestSpringInterceptor.java
new file mode 100644
index 0000000000..1f3a8d83e3
--- /dev/null
+++ b/cdi/src/test/java/com/baeldung/test/TestSpringInterceptor.java
@@ -0,0 +1,34 @@
+package com.baeldung.test;
+
+import static org.hamcrest.CoreMatchers.is;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.baeldung.spring.configuration.AppConfig;
+import com.baeldung.spring.service.SpringSuperService;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(classes = { AppConfig.class })
+public class TestSpringInterceptor {
+ @Autowired
+ SpringSuperService springSuperService;
+
+ @Autowired
+ private List accumulator;
+
+ @Test
+ public void givenService_whenServiceAndAspectExecuted_thenOk() {
+ String code = "123456";
+ String result = springSuperService.getInfoFromService(code);
+ Assert.assertThat(accumulator.size(), is(2));
+ Assert.assertThat(accumulator.get(0), is("Call to getInfoFromService"));
+ Assert.assertThat(accumulator.get(1), is("Method called successfully: getInfoFromService"));
+ }
+}
diff --git a/core-java-8/README.md b/core-java-8/README.md
index e6bac2a4c9..c130e6bd41 100644
--- a/core-java-8/README.md
+++ b/core-java-8/README.md
@@ -11,4 +11,14 @@
- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips)
- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator)
- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams)
-- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
\ No newline at end of file
+- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
+- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer)
+- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string)
+- [Guide to Java 8’s Functional Interfaces](http://www.baeldung.com/java-8-functional-interfaces)
+- [Guide To CompletableFuture](http://www.baeldung.com/java-completablefuture)
+- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava)
+- [Guide to Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
+- [The Java 8 Stream API Tutorial](http://www.baeldung.com/java-8-streams)
+- [New Features in Java 8](http://www.baeldung.com/java-8-new-features)
+- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction)
+- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml
index 63df0e1b95..566eb4e43a 100644
--- a/core-java-8/pom.xml
+++ b/core-java-8/pom.xml
@@ -1,9 +1,10 @@
4.0.0
+
com.baeldung
+ 1.0.0-SNAPSHOTcore-java8
- 0.1-SNAPSHOTcore-java8
@@ -111,6 +112,9 @@
+
+ UTF-8
+
1.7.131.0.13
diff --git a/core-java-8/src/main/java/com/baeldung/threadpool/CountingTask.java b/core-java-8/src/main/java/com/baeldung/threadpool/CountingTask.java
new file mode 100644
index 0000000000..05aa14c5ae
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/threadpool/CountingTask.java
@@ -0,0 +1,22 @@
+package com.baeldung.threadpool;
+
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.stream.Collectors;
+
+public class CountingTask extends RecursiveTask {
+
+ private final TreeNode node;
+
+ public CountingTask(TreeNode node) {
+ this.node = node;
+ }
+
+ @Override
+ protected Integer compute() {
+ return node.value + node.children.stream()
+ .map(childNode -> new CountingTask(childNode).fork())
+ .collect(Collectors.summingInt(ForkJoinTask::join));
+ }
+
+}
diff --git a/core-java-8/src/main/java/com/baeldung/threadpool/ExitingExecutorServiceExample.java b/core-java-8/src/main/java/com/baeldung/threadpool/ExitingExecutorServiceExample.java
new file mode 100644
index 0000000000..4775fde930
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/threadpool/ExitingExecutorServiceExample.java
@@ -0,0 +1,29 @@
+package com.baeldung.threadpool;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+ * This class demonstrates the usage of Guava's exiting executor services that keep the VM from hanging.
+ * Without the exiting executor service, the task would hang indefinitely.
+ * This behaviour cannot be demonstrated in JUnit tests, as JUnit kills the VM after the tests.
+ */
+public class ExitingExecutorServiceExample {
+
+ public static void main(String... args) {
+
+ ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
+ ExecutorService executorService = MoreExecutors.getExitingExecutorService(executor, 100, TimeUnit.MILLISECONDS);
+
+ executorService.submit(() -> {
+ while (true) {
+ }
+ });
+
+ }
+
+}
diff --git a/core-java-8/src/main/java/com/baeldung/threadpool/TreeNode.java b/core-java-8/src/main/java/com/baeldung/threadpool/TreeNode.java
new file mode 100644
index 0000000000..9b43152074
--- /dev/null
+++ b/core-java-8/src/main/java/com/baeldung/threadpool/TreeNode.java
@@ -0,0 +1,18 @@
+package com.baeldung.threadpool;
+
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+public class TreeNode {
+
+ int value;
+
+ Set children;
+
+ public TreeNode(int value, TreeNode... children) {
+ this.value = value;
+ this.children = Sets.newHashSet(children);
+ }
+
+}
diff --git a/core-java-8/src/main/resources/fileTest.txt b/core-java-8/src/main/resources/fileTest.txt
new file mode 100644
index 0000000000..ce4bea208b
--- /dev/null
+++ b/core-java-8/src/main/resources/fileTest.txt
@@ -0,0 +1 @@
+Hello World from fileTest.txt!!!
\ No newline at end of file
diff --git a/core-java-8/src/test/java/com/baeldung/CharToStringTest.java b/core-java-8/src/test/java/com/baeldung/CharToStringTest.java
new file mode 100644
index 0000000000..d91016d104
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/CharToStringTest.java
@@ -0,0 +1,53 @@
+package com.baeldung;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CharToStringTest {
+
+ @Test
+ public void givenChar_whenCallingStringValueOf_shouldConvertToString(){
+ final char givenChar = 'x';
+
+ final String result = String.valueOf(givenChar);
+
+ assertThat(result).isEqualTo("x");
+ }
+
+ @Test
+ public void givenChar_whenCallingToStringOnCharacter_shouldConvertToString(){
+ final char givenChar = 'x';
+
+ final String result = Character.toString(givenChar);
+
+ assertThat(result).isEqualTo("x");
+ }
+
+ @Test
+ public void givenChar_whenCallingCharacterConstructor_shouldConvertToString3(){
+ final char givenChar = 'x';
+
+ final String result = new Character(givenChar).toString();
+
+ assertThat(result).isEqualTo("x");
+ }
+
+ @Test
+ public void givenChar_whenConcatenated_shouldConvertToString4(){
+ final char givenChar = 'x';
+
+ final String result = givenChar + "";
+
+ assertThat(result).isEqualTo("x");
+ }
+
+ @Test
+ public void givenChar_whenFormated_shouldConvertToString5(){
+ final char givenChar = 'x';
+
+ final String result = String.format("%c", givenChar);
+
+ assertThat(result).isEqualTo("x");
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/RandomListElementTest.java b/core-java-8/src/test/java/com/baeldung/RandomListElementTest.java
new file mode 100644
index 0000000000..8143da5794
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/RandomListElementTest.java
@@ -0,0 +1,17 @@
+package com.baeldung;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+public class RandomListElementTest {
+
+ @Test
+ public void givenList_whenRandomNumberChosen_shouldReturnARandomElement() {
+ List givenList = Arrays.asList(1, 2, 3);
+ Random rand = new Random();
+ givenList.get(rand.nextInt(givenList.size()));
+ }
+}
diff --git a/core-java-8/src/test/java/com/baeldung/StringToIntOrIntegerTest.java b/core-java-8/src/test/java/com/baeldung/StringToIntOrIntegerTest.java
new file mode 100644
index 0000000000..6c1493d89b
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/StringToIntOrIntegerTest.java
@@ -0,0 +1,62 @@
+package com.baeldung;
+
+import com.google.common.primitives.Ints;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class StringToIntOrIntegerTest {
+
+ @Test
+ public void givenString_whenParsingInt_shouldConvertToInt() {
+ String givenString = "42";
+
+ int result = Integer.parseInt(givenString);
+
+ assertThat(result).isEqualTo(42);
+ }
+
+
+ @Test
+ public void givenString_whenCallingIntegerValueOf_shouldConvertToInt() {
+ String givenString = "42";
+
+ Integer result = Integer.valueOf(givenString);
+
+ assertThat(result).isEqualTo(new Integer(42));
+ }
+
+ @Test
+ public void givenString_whenCallingIntegerConstructor_shouldConvertToInt() {
+ String givenString = "42";
+
+ Integer result = new Integer(givenString);
+
+ assertThat(result).isEqualTo(new Integer(42));
+ }
+
+ @Test
+ public void givenString_whenCallingIntegerDecode_shouldConvertToInt() {
+ String givenString = "42";
+
+ int result = Integer.decode(givenString);
+
+ assertThat(result).isEqualTo(42);
+ }
+
+ @Test
+ public void givenString_whenTryParse_shouldConvertToInt() {
+ String givenString = "42";
+
+ Integer result = Ints.tryParse(givenString);
+
+ assertThat(result).isEqualTo(42);
+ }
+
+ @Test(expected = NumberFormatException.class)
+ public void givenInvalidInput_whenParsingInt_shouldThrow() {
+ String givenString = "nan";
+ Integer.parseInt(givenString);
+ }
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/completablefuture/CompletableFutureTest.java b/core-java-8/src/test/java/com/baeldung/completablefuture/CompletableFutureTest.java
new file mode 100644
index 0000000000..5363a73afa
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/completablefuture/CompletableFutureTest.java
@@ -0,0 +1,209 @@
+package com.baeldung.completablefuture;
+
+import java.util.concurrent.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class CompletableFutureTest {
+
+ @Test
+ public void whenRunningCompletableFutureAsynchronously_thenGetMethodWaitsForResult() throws InterruptedException, ExecutionException {
+
+ Future completableFuture = calculateAsync();
+
+ String result = completableFuture.get();
+ assertEquals("Hello", result);
+
+ }
+
+ public Future calculateAsync() throws InterruptedException {
+ CompletableFuture completableFuture = new CompletableFuture<>();
+
+ Executors.newCachedThreadPool().submit(() -> {
+ Thread.sleep(500);
+ completableFuture.complete("Hello");
+ return null;
+ });
+
+ return completableFuture;
+ }
+
+ @Test
+ public void whenRunningCompletableFutureWithResult_thenGetMethodReturnsImmediately() throws InterruptedException, ExecutionException {
+
+ Future completableFuture = CompletableFuture.completedFuture("Hello");
+
+ String result = completableFuture.get();
+ assertEquals("Hello", result);
+
+ }
+
+
+ public Future calculateAsyncWithCancellation() throws InterruptedException {
+ CompletableFuture completableFuture = new CompletableFuture<>();
+
+ Executors.newCachedThreadPool().submit(() -> {
+ Thread.sleep(500);
+ completableFuture.cancel(false);
+ return null;
+ });
+
+ return completableFuture;
+ }
+
+
+ @Test(expected = CancellationException.class)
+ public void whenCancelingTheFuture_thenThrowsCancellationException() throws ExecutionException, InterruptedException {
+
+ Future future = calculateAsyncWithCancellation();
+ future.get();
+
+ }
+
+ @Test
+ public void whenCreatingCompletableFutureWithSupplyAsync_thenFutureReturnsValue() throws ExecutionException, InterruptedException {
+
+ CompletableFuture future = CompletableFuture.supplyAsync(() -> "Hello");
+
+ assertEquals("Hello", future.get());
+
+ }
+
+ @Test
+ public void whenAddingThenAcceptToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
+
+ CompletableFuture future = completableFuture.thenAccept(s -> System.out.println("Computation returned: " + s));
+
+ future.get();
+
+ }
+
+ @Test
+ public void whenAddingThenRunToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
+
+ CompletableFuture future = completableFuture.thenRun(() -> System.out.println("Computation finished."));
+
+ future.get();
+
+ }
+
+ @Test
+ public void whenAddingThenApplyToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
+
+ CompletableFuture future = completableFuture.thenApply(s -> s + " World");
+
+ assertEquals("Hello World", future.get());
+
+ }
+
+ @Test
+ public void whenUsingThenCompose_thenFuturesExecuteSequentially() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello")
+ .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World"));
+
+ assertEquals("Hello World", completableFuture.get());
+
+ }
+
+ @Test
+ public void whenUsingThenCombine_thenWaitForExecutionOfBothFutures() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello")
+ .thenCombine(CompletableFuture.supplyAsync(() -> " World"),
+ (s1, s2) -> s1 + s2);
+
+ assertEquals("Hello World", completableFuture.get());
+
+ }
+
+ @Test
+ public void whenUsingThenAcceptBoth_thenWaitForExecutionOfBothFutures() throws ExecutionException, InterruptedException {
+
+ CompletableFuture.supplyAsync(() -> "Hello")
+ .thenAcceptBoth(CompletableFuture.supplyAsync(() -> " World"),
+ (s1, s2) -> System.out.println(s1 + s2));
+
+ }
+
+ @Test
+ public void whenFutureCombinedWithAllOfCompletes_thenAllFuturesAreDone() throws ExecutionException, InterruptedException {
+
+ CompletableFuture future1 = CompletableFuture.supplyAsync(() -> "Hello");
+ CompletableFuture future2 = CompletableFuture.supplyAsync(() -> "Beautiful");
+ CompletableFuture future3 = CompletableFuture.supplyAsync(() -> "World");
+
+ CompletableFuture combinedFuture = CompletableFuture.allOf(future1, future2, future3);
+
+ // ...
+
+ combinedFuture.get();
+
+ assertTrue(future1.isDone());
+ assertTrue(future2.isDone());
+ assertTrue(future3.isDone());
+
+ String combined = Stream.of(future1, future2, future3)
+ .map(CompletableFuture::join)
+ .collect(Collectors.joining(" "));
+
+ assertEquals("Hello Beautiful World", combined);
+
+ }
+
+ @Test
+ public void whenFutureThrows_thenHandleMethodReceivesException() throws ExecutionException, InterruptedException {
+
+ String name = null;
+
+ // ...
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
+ if (name == null) {
+ throw new RuntimeException("Computation error!");
+ }
+ return "Hello, " + name;
+ }).handle((s, t) -> s != null ? s : "Hello, Stranger!");
+
+ assertEquals("Hello, Stranger!", completableFuture.get());
+
+ }
+
+ @Test(expected = ExecutionException.class)
+ public void whenCompletingFutureExceptionally_thenGetMethodThrows() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = new CompletableFuture<>();
+
+ // ...
+
+ completableFuture.completeExceptionally(new RuntimeException("Calculation failed!"));
+
+ // ...
+
+ completableFuture.get();
+
+ }
+
+ @Test
+ public void whenAddingThenApplyAsyncToFuture_thenFunctionExecutesAfterComputationIsFinished() throws ExecutionException, InterruptedException {
+
+ CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
+
+ CompletableFuture future = completableFuture.thenApplyAsync(s -> s + " World");
+
+ assertEquals("Hello World", future.get());
+
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-8/src/test/java/com/baeldung/file/FileOperationsTest.java b/core-java-8/src/test/java/com/baeldung/file/FileOperationsTest.java
new file mode 100644
index 0000000000..b1476b6360
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/file/FileOperationsTest.java
@@ -0,0 +1,78 @@
+package com.baeldung.file;
+
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+
+import static org.hamcrest.CoreMatchers.containsString;
+
+public class FileOperationsTest {
+
+ @Test
+ public void givenFileName_whenUsingClassloader_thenFileData() throws IOException {
+ String expectedData = "Hello World from fileTest.txt!!!";
+
+ ClassLoader classLoader = getClass().getClassLoader();
+ InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+}
+
+ @Test
+ public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() throws IOException {
+ String expectedData = "Hello World from fileTest.txt!!!";
+
+ Class clazz = FileOperationsTest.class;
+ InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+ }
+
+ @Test
+ public void givenURLName_whenUsingURL_thenFileData() throws IOException {
+ String expectedData = "Baeldung";
+
+ URL urlObject = new URL("http://www.baeldung.com/");
+ URLConnection urlConnection = urlObject.openConnection();
+
+ InputStream inputStream = urlConnection.getInputStream();
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+ }
+
+ @Test
+ public void givenFileName_whenUsingJarFile_thenFileData() throws IOException {
+ String expectedData = "BSD License";
+
+ Class clazz = Matchers.class;
+ InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+ }
+
+ private String readFromInputStream(InputStream inputStream) throws IOException {
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+ BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+ StringBuilder resultStringBuilder = new StringBuilder();
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ resultStringBuilder.append(line);
+ resultStringBuilder.append("\n");
+ }
+ bufferedReader.close();
+ inputStreamReader.close();
+ inputStream.close();
+ return resultStringBuilder.toString();
+ }
+}
\ No newline at end of file
diff --git a/core-java-8/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceTest.java b/core-java-8/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceTest.java
new file mode 100644
index 0000000000..ce878026d4
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/functionalinterface/FunctionalInterfaceTest.java
@@ -0,0 +1,199 @@
+package com.baeldung.functionalinterface;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.google.common.util.concurrent.Uninterruptibles;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class FunctionalInterfaceTest {
+
+ @Test
+ public void whenPassingLambdaToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() {
+
+ Map nameMap = new HashMap<>();
+ Integer value = nameMap.computeIfAbsent("John", s -> s.length());
+
+ assertEquals(new Integer(4), nameMap.get("John"));
+ assertEquals(new Integer(4), value);
+
+ }
+
+ @Test
+ public void whenPassingMethodReferenceToComputeIfAbsent_thenTheValueGetsComputedAndPutIntoMap() {
+
+ Map nameMap = new HashMap<>();
+ Integer value = nameMap.computeIfAbsent("John", String::length);
+
+ assertEquals(new Integer(4), nameMap.get("John"));
+ assertEquals(new Integer(4), value);
+
+ }
+
+ public byte[] transformArray(short[] array, ShortToByteFunction function) {
+ byte[] transformedArray = new byte[array.length];
+ for (int i = 0; i < array.length; i++) {
+ transformedArray[i] = function.applyAsByte(array[i]);
+ }
+ return transformedArray;
+ }
+
+ @Test
+ public void whenUsingCustomFunctionalInterfaceForPrimitives_thenCanUseItAsLambda() {
+
+ short[] array = {(short) 1, (short) 2, (short) 3};
+ byte[] transformedArray = transformArray(array, s -> (byte) (s * 2));
+
+ byte[] expectedArray = {(byte) 2, (byte) 4, (byte) 6};
+ assertArrayEquals(expectedArray, transformedArray);
+
+ }
+
+ @Test
+ public void whenUsingBiFunction_thenCanUseItToReplaceMapValues() {
+
+ Map salaries = new HashMap<>();
+ salaries.put("John", 40000);
+ salaries.put("Freddy", 30000);
+ salaries.put("Samuel", 50000);
+
+ salaries.replaceAll((name, oldValue) -> name.equals("Freddy") ? oldValue : oldValue + 10000);
+
+ assertEquals(new Integer(50000), salaries.get("John"));
+ assertEquals(new Integer(30000), salaries.get("Freddy"));
+ assertEquals(new Integer(60000), salaries.get("Samuel"));
+
+ }
+
+
+ @Test
+ public void whenPassingLambdaToThreadConstructor_thenLambdaInferredToRunnable() {
+
+ Thread thread = new Thread(() -> System.out.println("Hello From Another Thread"));
+ thread.start();
+
+ }
+
+ @Test
+ public void whenUsingSupplierToGenerateNumbers_thenCanUseItInStreamGenerate() {
+
+ int[] fibs = {0, 1};
+ Stream fibonacci = Stream.generate(() -> {
+ int result = fibs[1];
+ int fib3 = fibs[0] + fibs[1];
+ fibs[0] = fibs[1];
+ fibs[1] = fib3;
+ return result;
+ });
+
+ List fibonacci5 = fibonacci.limit(5)
+ .collect(Collectors.toList());
+
+ assertEquals(new Integer(1), fibonacci5.get(0));
+ assertEquals(new Integer(1), fibonacci5.get(1));
+ assertEquals(new Integer(2), fibonacci5.get(2));
+ assertEquals(new Integer(3), fibonacci5.get(3));
+ assertEquals(new Integer(5), fibonacci5.get(4));
+
+ }
+
+ @Test
+ public void whenUsingConsumerInForEach_thenConsumerExecutesForEachListElement() {
+
+ List names = Arrays.asList("John", "Freddy", "Samuel");
+ names.forEach(name -> System.out.println("Hello, " + name));
+
+ }
+
+ @Test
+ public void whenUsingBiConsumerInForEach_thenConsumerExecutesForEachMapElement() {
+
+ Map ages = new HashMap<>();
+ ages.put("John", 25);
+ ages.put("Freddy", 24);
+ ages.put("Samuel", 30);
+
+ ages.forEach((name, age) -> System.out.println(name + " is " + age + " years old"));
+
+ }
+
+ @Test
+ public void whenUsingPredicateInFilter_thenListValuesAreFilteredOut() {
+
+ List names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David");
+
+ List namesWithA = names.stream()
+ .filter(name -> name.startsWith("A"))
+ .collect(Collectors.toList());
+
+ assertEquals(2, namesWithA.size());
+ assertTrue(namesWithA.contains("Angela"));
+ assertTrue(namesWithA.contains("Aaron"));
+
+ }
+
+ @Test
+ public void whenUsingUnaryOperatorWithReplaceAll_thenAllValuesInTheListAreReplaced() {
+
+ List names = Arrays.asList("bob", "josh", "megan");
+
+ names.replaceAll(String::toUpperCase);
+
+ assertEquals("BOB", names.get(0));
+ assertEquals("JOSH", names.get(1));
+ assertEquals("MEGAN", names.get(2));
+
+ }
+
+ @Test
+ public void whenUsingBinaryOperatorWithStreamReduce_thenResultIsSumOfValues() {
+
+ List values = Arrays.asList(3, 5, 8, 9, 12);
+
+ int sum = values.stream()
+ .reduce(0, (i1, i2) -> i1 + i2);
+
+ assertEquals(37, sum);
+
+ }
+
+ @Test
+ public void whenComposingTwoFunctions_thenFunctionsExecuteSequentially() {
+
+ Function intToString = Object::toString;
+ Function quote = s -> "'" + s + "'";
+
+ Function quoteIntToString = quote.compose(intToString);
+
+ assertEquals("'5'", quoteIntToString.apply(5));
+
+ }
+
+ public double squareLazy(Supplier lazyValue) {
+ return Math.pow(lazyValue.get(), 2);
+ }
+
+ @Test
+ public void whenUsingSupplierToGenerateValue_thenValueIsGeneratedLazily() {
+
+ Supplier lazyValue = () -> {
+ Uninterruptibles.sleepUninterruptibly(1000, TimeUnit.MILLISECONDS);
+ return 9d;
+ };
+
+ double valueSquared = squareLazy(lazyValue);
+
+ assertEquals(81d, valueSquared, 0);
+
+ }
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java b/core-java-8/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java
new file mode 100644
index 0000000000..3231d6244f
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/functionalinterface/ShortToByteFunction.java
@@ -0,0 +1,8 @@
+package com.baeldung.functionalinterface;
+
+@FunctionalInterface
+public interface ShortToByteFunction {
+
+ byte applyAsByte(short s);
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java b/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java
index efd548a4b1..f2e7452137 100644
--- a/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java
+++ b/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java
@@ -21,7 +21,7 @@ public class JavaFolderSizeTest {
@Before
public void init() {
final String separator = File.separator;
- path = "src" + separator + "test" + separator + "resources";
+ path = String.format("src%stest%sresources", separator, separator);
}
@Test
@@ -79,7 +79,9 @@ public class JavaFolderSizeTest {
final File folder = new File(path);
final Iterable files = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder);
- final long size = StreamSupport.stream(files.spliterator(), false).filter(f -> f.isFile()).mapToLong(File::length).sum();
+ final long size = StreamSupport.stream(files.spliterator(), false)
+ .filter(File::isFile)
+ .mapToLong(File::length).sum();
assertEquals(expectedSize, size);
}
@@ -101,13 +103,11 @@ public class JavaFolderSizeTest {
long length = 0;
final File[] files = folder.listFiles();
- final int count = files.length;
-
- for (int i = 0; i < count; i++) {
- if (files[i].isFile()) {
- length += files[i].length();
+ for (File file : files) {
+ if (file.isFile()) {
+ length += file.length();
} else {
- length += getFolderSize(files[i]);
+ length += getFolderSize(file);
}
}
return length;
diff --git a/core-java-8/src/test/java/com/baeldung/threadpool/CoreThreadPoolTest.java b/core-java-8/src/test/java/com/baeldung/threadpool/CoreThreadPoolTest.java
new file mode 100644
index 0000000000..df336f4a93
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/threadpool/CoreThreadPoolTest.java
@@ -0,0 +1,146 @@
+package com.baeldung.threadpool;
+
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class CoreThreadPoolTest {
+
+ @Test(timeout = 1000)
+ public void whenCallingExecuteWithRunnable_thenRunnableIsExecuted() throws InterruptedException {
+
+ CountDownLatch lock = new CountDownLatch(1);
+
+ Executor executor = Executors.newSingleThreadExecutor();
+ executor.execute(() -> {
+ System.out.println("Hello World");
+ lock.countDown();
+ });
+
+ lock.await(1000, TimeUnit.MILLISECONDS);
+ }
+
+ @Test
+ public void whenUsingExecutorServiceAndFuture_thenCanWaitOnFutureResult() throws InterruptedException, ExecutionException {
+
+ ExecutorService executorService = Executors.newFixedThreadPool(10);
+ Future future = executorService.submit(() -> "Hello World");
+ String result = future.get();
+
+ assertEquals("Hello World", result);
+
+ }
+
+ @Test
+ public void whenUsingFixedThreadPool_thenCoreAndMaximumThreadSizeAreTheSame() {
+
+ ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
+ executor.submit(() -> {
+ Thread.sleep(1000);
+ return null;
+ });
+ executor.submit(() -> {
+ Thread.sleep(1000);
+ return null;
+ });
+ executor.submit(() -> {
+ Thread.sleep(1000);
+ return null;
+ });
+
+ assertEquals(2, executor.getPoolSize());
+ assertEquals(1, executor.getQueue().size());
+
+ }
+
+ @Test
+ public void whenUsingCachedThreadPool_thenPoolSizeGrowsUnbounded() {
+ ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
+ executor.submit(() -> {
+ Thread.sleep(1000);
+ return null;
+ });
+ executor.submit(() -> {
+ Thread.sleep(1000);
+ return null;
+ });
+ executor.submit(() -> {
+ Thread.sleep(1000);
+ return null;
+ });
+
+ assertEquals(3, executor.getPoolSize());
+ assertEquals(0, executor.getQueue().size());
+
+ }
+
+ @Test(timeout = 1000)
+ public void whenUsingSingleThreadPool_thenTasksExecuteSequentially() throws InterruptedException {
+
+ CountDownLatch lock = new CountDownLatch(2);
+ AtomicInteger counter = new AtomicInteger();
+
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ executor.submit(() -> {
+ counter.set(1);
+ lock.countDown();
+ });
+ executor.submit(() -> {
+ counter.compareAndSet(1, 2);
+ lock.countDown();
+ });
+
+ lock.await(1000, TimeUnit.MILLISECONDS);
+ assertEquals(2, counter.get());
+
+ }
+
+ @Test(timeout = 1000)
+ public void whenSchedulingTask_thenTaskExecutesWithinGivenPeriod() throws InterruptedException {
+
+ CountDownLatch lock = new CountDownLatch(1);
+
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
+ executor.schedule(() -> {
+ System.out.println("Hello World");
+ lock.countDown();
+ }, 500, TimeUnit.MILLISECONDS);
+
+ lock.await(1000, TimeUnit.MILLISECONDS);
+
+ }
+
+ @Test(timeout = 1000)
+ public void whenSchedulingTaskWithFixedPeriod_thenTaskExecutesMultipleTimes() throws InterruptedException {
+
+ CountDownLatch lock = new CountDownLatch(3);
+
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
+ ScheduledFuture> future = executor.scheduleAtFixedRate(() -> {
+ System.out.println("Hello World");
+ lock.countDown();
+ }, 500, 100, TimeUnit.MILLISECONDS);
+
+ lock.await();
+ future.cancel(true);
+
+ }
+
+ @Test
+ public void whenUsingForkJoinPool_thenSumOfTreeElementsIsCalculatedCorrectly() {
+
+ TreeNode tree = new TreeNode(5,
+ new TreeNode(3), new TreeNode(2,
+ new TreeNode(2), new TreeNode(8)));
+
+ ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
+ int sum = forkJoinPool.invoke(new CountingTask(tree));
+
+ assertEquals(20, sum);
+ }
+
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/threadpool/GuavaThreadPoolTest.java b/core-java-8/src/test/java/com/baeldung/threadpool/GuavaThreadPoolTest.java
new file mode 100644
index 0000000000..92e0f9a8cb
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/threadpool/GuavaThreadPoolTest.java
@@ -0,0 +1,56 @@
+package com.baeldung.threadpool;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class GuavaThreadPoolTest {
+
+ @Test
+ public void whenExecutingTaskWithDirectExecutor_thenTheTaskIsExecutedInTheCurrentThread() {
+
+ Executor executor = MoreExecutors.directExecutor();
+
+ AtomicBoolean executed = new AtomicBoolean();
+
+ executor.execute(() -> {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ executed.set(true);
+ });
+
+ assertTrue(executed.get());
+ }
+
+ @Test
+ public void whenJoiningFuturesWithAllAsList_thenCombinedFutureCompletesAfterAllFuturesComplete() throws ExecutionException, InterruptedException {
+
+ ExecutorService executorService = Executors.newCachedThreadPool();
+ ListeningExecutorService listeningExecutorService = MoreExecutors.listeningDecorator(executorService);
+
+ ListenableFuture future1 = listeningExecutorService.submit(() -> "Hello");
+ ListenableFuture future2 = listeningExecutorService.submit(() -> "World");
+
+ String greeting = Futures.allAsList(future1, future2).get()
+ .stream()
+ .collect(Collectors.joining(" "));
+ assertEquals("Hello World", greeting);
+
+ }
+
+}
diff --git a/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeTest.java b/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeTest.java
new file mode 100644
index 0000000000..06d9394a5e
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.junit.Test;
+
+public class CurrentDateTimeTest {
+
+ @Test
+ public void shouldReturnCurrentDate() {
+
+ final LocalDate now = LocalDate.now();
+ final Calendar calendar = GregorianCalendar.getInstance();
+
+ assertEquals("10-10-2010".length(), now.toString().length());
+ assertEquals(calendar.get(Calendar.DATE), now.get(ChronoField.DAY_OF_MONTH));
+ assertEquals(calendar.get(Calendar.MONTH), now.get(ChronoField.MONTH_OF_YEAR) - 1);
+ assertEquals(calendar.get(Calendar.YEAR), now.get(ChronoField.YEAR));
+ }
+
+ @Test
+ public void shouldReturnCurrentTime() {
+
+ final LocalTime now = LocalTime.now();
+ final Calendar calendar = GregorianCalendar.getInstance();
+
+ assertEquals(calendar.get(Calendar.HOUR_OF_DAY), now.get(ChronoField.HOUR_OF_DAY));
+ assertEquals(calendar.get(Calendar.MINUTE), now.get(ChronoField.MINUTE_OF_HOUR));
+ assertEquals(calendar.get(Calendar.SECOND), now.get(ChronoField.SECOND_OF_MINUTE));
+ }
+
+ @Test
+ public void shouldReturnCurrentTimestamp() {
+
+ final Instant now = Instant.now();
+ final Calendar calendar = GregorianCalendar.getInstance();
+
+ assertEquals(calendar.getTimeInMillis() / 1000, now.getEpochSecond());
+ }
+}
diff --git a/core-java-8/src/test/resources/test.txt b/core-java-8/src/test/resources/test.txt
new file mode 100644
index 0000000000..652d70630f
--- /dev/null
+++ b/core-java-8/src/test/resources/test.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse facilisis neque sed turpis venenatis, non dignissim risus volutpat.
\ No newline at end of file
diff --git a/core-java-8/src/test/resources/.gitignore b/core-java-9/.gitignore
similarity index 100%
rename from core-java-8/src/test/resources/.gitignore
rename to core-java-9/.gitignore
diff --git a/core-java-9/README.md b/core-java-9/README.md
new file mode 100644
index 0000000000..b5d4dbef95
--- /dev/null
+++ b/core-java-9/README.md
@@ -0,0 +1,5 @@
+=========
+
+## Core Java 9 Examples
+
+http://inprogress.baeldung.com/java-9-new-features/
\ No newline at end of file
diff --git a/core-java-9/pom.xml b/core-java-9/pom.xml
new file mode 100644
index 0000000000..844ad6a782
--- /dev/null
+++ b/core-java-9/pom.xml
@@ -0,0 +1,93 @@
+
+ 4.0.0
+ com.baeldung
+ core-java9
+ 0.2-SNAPSHOT
+
+ core-java9
+
+
+
+ apache.snapshots
+ http://repository.apache.org/snapshots/
+
+
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+
+
+
+ org.hamcrest
+ hamcrest-library
+ ${org.hamcrest.version}
+ test
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+
+
+ core-java-9
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ 1.9
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+
+
+ 1.7.13
+ 1.0.13
+
+
+
+ 3.6-jigsaw-SNAPSHOT
+ 2.19.1
+
+
+ 1.3
+ 4.12
+ 1.10.19
+
+
+
diff --git a/core-java-9/src/main/java/.gitignore b/core-java-9/src/main/java/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/core-java-9/src/main/java/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java b/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java
new file mode 100644
index 0000000000..fd6a496b18
--- /dev/null
+++ b/core-java-9/src/main/java/com/baeldung/java9/language/PrivateInterface.java
@@ -0,0 +1,23 @@
+package com.baeldung.java9.language;
+
+public interface PrivateInterface {
+
+ private static String staticPrivate() {
+ return "static private";
+ }
+
+ private String instancePrivate() {
+ return "instance private";
+ }
+
+ public default void check(){
+ String result = staticPrivate();
+ if (!result.equals("static private"))
+ throw new AssertionError("Incorrect result for static private interface method");
+ PrivateInterface pvt = new PrivateInterface() {
+ };
+ result = pvt.instancePrivate();
+ if (!result.equals("instance private"))
+ throw new AssertionError("Incorrect result for instance private interface method");
+ }
+}
diff --git a/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUtils.java b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUtils.java
new file mode 100644
index 0000000000..d6682bd0c8
--- /dev/null
+++ b/core-java-9/src/main/java/com/baeldung/java9/process/ProcessUtils.java
@@ -0,0 +1,44 @@
+package com.baeldung.java9.process;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.stream.Stream;
+
+
+public class ProcessUtils {
+
+ public static String getClassPath(){
+ String cp = System.getProperty("java.class.path");
+ System.out.println("ClassPath is "+cp);
+ return cp;
+ }
+
+ public static File getJavaCmd() throws IOException{
+ String javaHome = System.getProperty("java.home");
+ File javaCmd;
+ if(System.getProperty("os.name").startsWith("Win")){
+ javaCmd = new File(javaHome, "bin/java.exe");
+ }else{
+ javaCmd = new File(javaHome, "bin/java");
+ }
+ if(javaCmd.canExecute()){
+ return javaCmd;
+ }else{
+ throw new UnsupportedOperationException(javaCmd.getCanonicalPath() + " is not executable");
+ }
+ }
+
+ public static String getMainClass(){
+ return System.getProperty("sun.java.command");
+ }
+
+ public static String getSystemProperties(){
+ StringBuilder sb = new StringBuilder();
+ System.getProperties().forEach((s1, s2) -> sb.append(s1 +" - "+ s2) );
+ return sb.toString();
+ }
+}
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
new file mode 100644
index 0000000000..458f746496
--- /dev/null
+++ b/core-java-9/src/main/java/com/baeldung/java9/process/ServiceMain.java
@@ -0,0 +1,22 @@
+package com.baeldung.java9.process;
+
+import java.util.Optional;
+
+public class ServiceMain {
+
+ public static void main(String[] args) throws InterruptedException {
+ ProcessHandle thisProcess = ProcessHandle.current();
+ long pid = thisProcess.getPid();
+
+
+ Optional opArgs = Optional.ofNullable(args);
+ String procName = opArgs.map(str -> str.length > 0 ? str[0] : null).orElse(System.getProperty("sun.java.command"));
+
+ for (int i = 0; i < 10000; i++) {
+ System.out.println("Process " + procName + " with ID " + pid + " is running!");
+ Thread.sleep(10000);
+ }
+
+ }
+
+}
diff --git a/core-java-9/src/main/resources/logback.xml b/core-java-9/src/main/resources/logback.xml
new file mode 100644
index 0000000000..eefdc7a337
--- /dev/null
+++ b/core-java-9/src/main/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java
new file mode 100644
index 0000000000..b0684a94f8
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java
@@ -0,0 +1,71 @@
+package com.baeldung.java8;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class Java9OptionalsStreamTest {
+
+ private static List> listOfOptionals = Arrays.asList(Optional.empty(), Optional.of("foo"), Optional.empty(), Optional.of("bar"));
+
+ @Test
+ public void filterOutPresentOptionalsWithFilter() {
+ assertEquals(4, listOfOptionals.size());
+
+ List filteredList = listOfOptionals.stream()
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .collect(Collectors.toList());
+
+ assertEquals(2, filteredList.size());
+ assertEquals("foo", filteredList.get(0));
+ assertEquals("bar", filteredList.get(1));
+ }
+
+ @Test
+ public void filterOutPresentOptionalsWithFlatMap() {
+ assertEquals(4, listOfOptionals.size());
+
+ List filteredList = listOfOptionals.stream()
+ .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
+ .collect(Collectors.toList());
+ assertEquals(2, filteredList.size());
+
+ assertEquals("foo", filteredList.get(0));
+ assertEquals("bar", filteredList.get(1));
+ }
+
+ @Test
+ public void filterOutPresentOptionalsWithFlatMap2() {
+ assertEquals(4, listOfOptionals.size());
+
+ List filteredList = listOfOptionals.stream()
+ .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
+ .collect(Collectors.toList());
+ assertEquals(2, filteredList.size());
+
+ assertEquals("foo", filteredList.get(0));
+ assertEquals("bar", filteredList.get(1));
+ }
+
+ @Test
+ public void filterOutPresentOptionalsWithJava9() {
+ assertEquals(4, listOfOptionals.size());
+
+ List filteredList = listOfOptionals.stream()
+ .flatMap(Optional::stream)
+ .collect(Collectors.toList());
+
+ assertEquals(2, filteredList.size());
+ assertEquals("foo", filteredList.get(0));
+ assertEquals("bar", filteredList.get(1));
+ }
+
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java b/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java
new file mode 100644
index 0000000000..a00646e4db
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.java9;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import java.awt.Image;
+import java.awt.image.BaseMultiResolutionImage;
+import java.awt.image.BufferedImage;
+import java.awt.image.MultiResolutionImage;
+import java.util.List;
+
+import org.junit.Test;
+
+public class MultiResultionImageTest {
+
+
+ @Test
+ public void baseMultiResImageTest() {
+ int baseIndex = 1;
+ int length = 4;
+ BufferedImage[] resolutionVariants = new BufferedImage[length];
+ for (int i = 0; i < length; i++) {
+ resolutionVariants[i] = createImage(i);
+ }
+ MultiResolutionImage bmrImage = new BaseMultiResolutionImage(baseIndex, resolutionVariants);
+ List rvImageList = bmrImage.getResolutionVariants();
+ assertEquals("MultiResoltion Image shoudl contain the same number of resolution variants!", rvImageList.size(), length);
+
+ for (int i = 0; i < length; i++) {
+ int imageSize = getSize(i);
+ Image testRVImage = bmrImage.getResolutionVariant(imageSize, imageSize);
+ assertSame("Images should be the same", testRVImage, resolutionVariants[i]);
+ }
+
+ }
+
+ private static int getSize(int i) {
+ return 8 * (i + 1);
+ }
+
+
+ private static BufferedImage createImage(int i) {
+ return new BufferedImage(getSize(i), getSize(i),
+ BufferedImage.TYPE_INT_RGB);
+ }
+
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java b/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java
new file mode 100644
index 0000000000..56b4bb7b8c
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.java9;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class OptionalToStreamTest {
+
+ @Test
+ public void testOptionalToStream() {
+ Optional op = Optional.ofNullable("String value");
+ Stream strOptionalStream = op.stream();
+ Stream filteredStream = strOptionalStream.filter((str) -> {
+ return str != null && str.startsWith("String");
+ });
+ assertEquals(1, filteredStream.count());
+
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java b/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java
new file mode 100644
index 0000000000..0f8db83d9c
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.java9;
+
+import java.util.Set;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SetExamplesTest {
+
+ @Test
+ public void testUnmutableSet() {
+ Set strKeySet = Set.of("key1", "key2", "key3");
+ try {
+ strKeySet.add("newKey");
+ } catch (UnsupportedOperationException uoe) {
+ }
+ assertEquals(strKeySet.size(), 3);
+ }
+
+ @Test
+ public void testArrayToSet() {
+ Integer[] intArray = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+ Set intSet = Set.of(intArray);
+ assertEquals(intSet.size(), intArray.length);
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsTest.java b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsTest.java
new file mode 100644
index 0000000000..ab28b0a805
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/httpclient/SimpleHttpRequestsTest.java
@@ -0,0 +1,126 @@
+package com.baeldung.java9.httpclient;
+
+
+
+import static java.net.HttpURLConnection.HTTP_OK;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.http.HttpClient;
+import java.net.http.HttpHeaders;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class SimpleHttpRequestsTest {
+
+ private URI httpURI;
+
+ @Before
+ public void init() throws URISyntaxException {
+ httpURI = new URI("http://www.baeldung.com/");
+ }
+
+ @Test
+ public void quickGet() throws IOException, InterruptedException, URISyntaxException {
+ HttpRequest request = HttpRequest.create( httpURI ).GET();
+ HttpResponse response = request.response();
+ int responseStatusCode = response.statusCode();
+ String responseBody = response.body(HttpResponse.asString());
+ assertTrue("Get response status code is bigger then 400", responseStatusCode < 400);
+ }
+
+ @Test
+ public void asynchronousGet() throws URISyntaxException, IOException, InterruptedException, ExecutionException{
+ HttpRequest request = HttpRequest.create(httpURI).GET();
+ long before = System.currentTimeMillis();
+ CompletableFuture futureResponse = request.responseAsync();
+ futureResponse.thenAccept( response -> {
+ String responseBody = response.body(HttpResponse.asString());
+ });
+ HttpResponse resp = futureResponse.get();
+ HttpHeaders hs = resp.headers();
+ assertTrue("There should be more then 1 header.", hs.map().size() >1);
+ }
+
+ @Test
+ public void postMehtod() throws URISyntaxException, IOException, InterruptedException {
+ HttpRequest.Builder requestBuilder = HttpRequest.create(httpURI);
+ requestBuilder.body(HttpRequest.fromString("param1=foo,param2=bar")).followRedirects(HttpClient.Redirect.SECURE);
+ HttpRequest request = requestBuilder.POST();
+ HttpResponse response = request.response();
+ int statusCode = response.statusCode();
+ assertTrue("HTTP return code", statusCode == HTTP_OK);
+ }
+
+ @Test
+ public void configureHttpClient() throws NoSuchAlgorithmException, URISyntaxException, IOException, InterruptedException{
+ CookieManager cManager = new CookieManager();
+ cManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
+
+ SSLParameters sslParam = new SSLParameters (new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" }, new String[] { "TLSv1.2" });
+
+ HttpClient.Builder hcBuilder = HttpClient.create();
+ hcBuilder.cookieManager(cManager).sslContext(SSLContext.getDefault()).sslParameters(sslParam);
+ HttpClient httpClient = hcBuilder.build();
+ HttpRequest.Builder reqBuilder = httpClient.request(new URI("https://www.facebook.com"));
+
+ HttpRequest request = reqBuilder.followRedirects(HttpClient.Redirect.ALWAYS).GET();
+ HttpResponse response = request.response();
+ int statusCode = response.statusCode();
+ assertTrue("HTTP return code", statusCode == HTTP_OK);
+ }
+
+ SSLParameters getDefaultSSLParameters() throws NoSuchAlgorithmException{
+ SSLParameters sslP1 = SSLContext.getDefault().getSupportedSSLParameters();
+ String [] proto = sslP1.getApplicationProtocols();
+ String [] cifers = sslP1.getCipherSuites();
+ System.out.println(printStringArr(proto));
+ System.out.println(printStringArr(cifers));
+ return sslP1;
+ }
+
+ String printStringArr(String ... args ){
+ if(args == null){
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (String s : args){
+ sb.append(s);
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ String printHeaders(HttpHeaders h){
+ if(h == null){
+ return null;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ Map> hMap = h.map();
+ for(String k : hMap.keySet()){
+ sb.append(k).append(":");
+ List l = hMap.get(k);
+ if( l != null ){
+ l.forEach( s -> { sb.append(s).append(","); } );
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/DiamondTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/DiamondTest.java
new file mode 100644
index 0000000000..33da6486f4
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/language/DiamondTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.java9.language;
+
+import org.junit.Test;
+
+public class DiamondTest {
+
+ static class FooClass {
+ FooClass(X x) {
+ }
+
+ FooClass(X x, Z z) {
+ }
+ }
+
+ @Test
+ public void diamondTest() {
+ FooClass fc = new FooClass<>(1) {
+ };
+ FooClass extends Integer> fc0 = new FooClass<>(1) {
+ };
+ FooClass> fc1 = new FooClass<>(1) {
+ };
+ FooClass super Integer> fc2 = new FooClass<>(1) {
+ };
+
+ FooClass fc3 = new FooClass<>(1, "") {
+ };
+ FooClass extends Integer> fc4 = new FooClass<>(1, "") {
+ };
+ FooClass> fc5 = new FooClass<>(1, "") {
+ };
+ FooClass super Integer> fc6 = new FooClass<>(1, "") {
+ };
+
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceTest.java
new file mode 100644
index 0000000000..29ef3930f8
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/language/PrivateInterfaceTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.java9.language;
+
+import com.baeldung.java9.language.PrivateInterface;
+import org.junit.Test;
+
+public class PrivateInterfaceTest {
+
+ @Test
+ public void test() {
+ PrivateInterface piClass = new PrivateInterface() {
+ };
+ piClass.check();
+ }
+
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesTest.java b/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesTest.java
new file mode 100644
index 0000000000..687dfbc390
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/language/TryWithResourcesTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.java9.language;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class TryWithResourcesTest {
+
+ static int closeCount = 0;
+
+ static class MyAutoCloseable implements AutoCloseable{
+ final FinalWrapper finalWrapper = new FinalWrapper();
+
+ public void close() {
+ closeCount++;
+ }
+
+ static class FinalWrapper {
+ public final AutoCloseable finalCloseable = new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ closeCount++;
+ }
+ };
+ }
+ }
+
+ @Test
+ public void tryWithResourcesTest() {
+ MyAutoCloseable mac = new MyAutoCloseable();
+
+ try (mac) {
+ assertEquals("Expected and Actual does not match", 0, closeCount);
+ }
+
+ try (mac.finalWrapper.finalCloseable) {
+ assertEquals("Expected and Actual does not match", 1, closeCount);
+ } catch (Exception ex) {
+ }
+
+ try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
+ assertEquals("Expected and Actual does not match", 2, closeCount);
+ } catch (Exception ex) {
+ }
+
+ try ((closeCount > 0 ? mac : new MyAutoCloseable()).finalWrapper.finalCloseable) {
+ assertEquals("Expected and Actual does not match", 3, closeCount);
+ } catch (Exception ex) {
+ }
+
+ try {
+ throw new CloseableException();
+ } catch (CloseableException ex) {
+ try (ex) {
+ assertEquals("Expected and Actual does not match", 4, closeCount);
+ }
+ }
+ assertEquals("Expected and Actual does not match", 5, closeCount);
+ }
+
+
+ static class CloseableException extends Exception implements AutoCloseable {
+ @Override
+ public void close() {
+ closeCount++;
+ }
+ }
+
+}
+
+
diff --git a/core-java-9/src/test/java/com/baeldung/java9/process/ProcessApi.java b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessApi.java
new file mode 100644
index 0000000000..419516cb64
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/process/ProcessApi.java
@@ -0,0 +1,112 @@
+package com.baeldung.java9.process;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ProcessApi {
+
+
+ @Before
+ public void init() {
+
+ }
+
+ @Test
+ public void processInfoExample()throws NoSuchAlgorithmException{
+ ProcessHandle self = ProcessHandle.current();
+ long PID = self.getPid();
+ ProcessHandle.Info procInfo = self.info();
+ Optional args = procInfo.arguments();
+ Optional cmd = procInfo.commandLine();
+ Optional startTime = procInfo.startInstant();
+ Optional cpuUsage = procInfo.totalCpuDuration();
+
+ waistCPU();
+ System.out.println("Args "+ args);
+ System.out.println("Command " +cmd.orElse("EmptyCmd"));
+ System.out.println("Start time: "+ startTime.get().toString());
+ System.out.println(cpuUsage.get().toMillis());
+
+ Stream allProc = ProcessHandle.current().children();
+ allProc.forEach(p -> {
+ System.out.println("Proc "+ p.getPid());
+ });
+
+ }
+
+ @Test
+ public void createAndDestroyProcess() throws IOException, InterruptedException{
+ int numberOfChildProcesses = 5;
+ for(int i=0; i < numberOfChildProcesses; i++){
+ createNewJVM(ServiceMain.class, i).getPid();
+ }
+
+ Stream childProc = ProcessHandle.current().children();
+ assertEquals( childProc.count(), numberOfChildProcesses);
+
+ childProc = ProcessHandle.current().children();
+ childProc.forEach(processHandle -> {
+ assertTrue("Process "+ processHandle.getPid() +" should be alive!", processHandle.isAlive());
+ CompletableFuture onProcExit = processHandle.onExit();
+ onProcExit.thenAccept(procHandle -> {
+ System.out.println("Process with PID "+ procHandle.getPid() + " has stopped");
+ });
+ });
+
+ Thread.sleep(10000);
+
+ childProc = ProcessHandle.current().children();
+ childProc.forEach(procHandle -> {
+ assertTrue("Could not kill process "+procHandle.getPid(), procHandle.destroy());
+ });
+
+ Thread.sleep(5000);
+
+ childProc = ProcessHandle.current().children();
+ childProc.forEach(procHandle -> {
+ assertFalse("Process "+ procHandle.getPid() +" should not be alive!", procHandle.isAlive());
+ });
+
+ }
+
+ private Process createNewJVM(Class mainClass, int number) throws IOException{
+ ArrayList cmdParams = new ArrayList(5);
+ cmdParams.add(ProcessUtils.getJavaCmd().getAbsolutePath());
+ cmdParams.add("-cp");
+ cmdParams.add(ProcessUtils.getClassPath());
+ cmdParams.add(mainClass.getName());
+ cmdParams.add("Service "+ number);
+ ProcessBuilder myService = new ProcessBuilder(cmdParams);
+ myService.inheritIO();
+ return myService.start();
+ }
+
+ private void waistCPU() throws NoSuchAlgorithmException{
+ ArrayList randArr = new ArrayList(4096);
+ SecureRandom sr = SecureRandom.getInstanceStrong();
+ Duration somecpu = Duration.ofMillis(4200L);
+ Instant end = Instant.now().plus(somecpu);
+ while (Instant.now().isBefore(end)) {
+ //System.out.println(sr.nextInt());
+ randArr.add( sr.nextInt() );
+ }
+ }
+
+}
diff --git a/core-java-9/src/test/resources/.gitignore b/core-java-9/src/test/resources/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/core-java-9/src/test/resources/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/core-java/pom.xml b/core-java/pom.xml
index bc533607e7..bce97d1148 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -123,6 +123,12 @@
${mockito.version}test
+
+
+ commons-codec
+ commons-codec
+ 1.10
+
diff --git a/core-java/src/main/java/com/baeldung/core/exceptions/FileNotFoundExceptionExample.java b/core-java/src/main/java/com/baeldung/core/exceptions/FileNotFoundExceptionExample.java
new file mode 100644
index 0000000000..2ac4e49869
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/core/exceptions/FileNotFoundExceptionExample.java
@@ -0,0 +1,20 @@
+package com.baeldung.core.exceptions;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class FileNotFoundExceptionExample {
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader rd = null;
+ try {
+ rd = new BufferedReader(new FileReader(new File("notExisting")));
+ rd.readLine();
+ } catch (FileNotFoundException ex) {
+ ex.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Animal.java b/core-java/src/main/java/com/baeldung/java/reflection/Animal.java
new file mode 100644
index 0000000000..3f36243c29
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/reflection/Animal.java
@@ -0,0 +1,23 @@
+package com.baeldung.java.reflection;
+
+public abstract class Animal implements Eating {
+
+ public static final String CATEGORY = "domestic";
+
+ private String name;
+
+ public Animal(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ protected abstract String getSound();
+
+}
diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Bird.java b/core-java/src/main/java/com/baeldung/java/reflection/Bird.java
new file mode 100644
index 0000000000..bd6f13094c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/reflection/Bird.java
@@ -0,0 +1,36 @@
+package com.baeldung.java.reflection;
+
+public class Bird extends Animal {
+ private boolean walks;
+
+ public Bird() {
+ super("bird");
+ }
+
+ public Bird(String name, boolean walks) {
+ super(name);
+ setWalks(walks);
+ }
+
+ public Bird(String name) {
+ super(name);
+ }
+
+ @Override
+ public String eats() {
+ return "grains";
+ }
+
+ @Override
+ protected String getSound() {
+ return "chaps";
+ }
+
+ public boolean walks() {
+ return walks;
+ }
+
+ public void setWalks(boolean walks) {
+ this.walks = walks;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Eating.java b/core-java/src/main/java/com/baeldung/java/reflection/Eating.java
new file mode 100644
index 0000000000..479425cad4
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/reflection/Eating.java
@@ -0,0 +1,5 @@
+package com.baeldung.java.reflection;
+
+public interface Eating {
+ String eats();
+}
diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Goat.java b/core-java/src/main/java/com/baeldung/java/reflection/Goat.java
new file mode 100644
index 0000000000..503717ae5e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/reflection/Goat.java
@@ -0,0 +1,24 @@
+package com.baeldung.java.reflection;
+
+public class Goat extends Animal implements Locomotion {
+
+ public Goat(String name) {
+ super(name);
+ }
+
+ @Override
+ protected String getSound() {
+ return "bleat";
+ }
+
+ @Override
+ public String getLocomotion() {
+ return "walks";
+ }
+
+ @Override
+ public String eats() {
+ return "grass";
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Locomotion.java b/core-java/src/main/java/com/baeldung/java/reflection/Locomotion.java
new file mode 100644
index 0000000000..047c00cb13
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/reflection/Locomotion.java
@@ -0,0 +1,5 @@
+package com.baeldung.java.reflection;
+
+public interface Locomotion {
+ String getLocomotion();
+}
diff --git a/core-java/src/main/java/com/baeldung/java/reflection/Person.java b/core-java/src/main/java/com/baeldung/java/reflection/Person.java
new file mode 100644
index 0000000000..f3d7f9f001
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/reflection/Person.java
@@ -0,0 +1,6 @@
+package com.baeldung.java.reflection;
+
+public class Person {
+ private String name;
+ private int age;
+}
diff --git a/core-java/src/main/java/com/baeldung/java/regex/Result.java b/core-java/src/main/java/com/baeldung/java/regex/Result.java
new file mode 100644
index 0000000000..d47c94ad2e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/regex/Result.java
@@ -0,0 +1,27 @@
+package com.baeldung.java.regex;
+
+public class Result {
+ private boolean found = false;
+ private int count = 0;
+
+ public Result() {
+
+ }
+
+ public boolean isFound() {
+ return found;
+ }
+
+ public void setFound(boolean found) {
+ this.found = found;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+}
diff --git a/core-java/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java
new file mode 100644
index 0000000000..d4a6a0f42e
--- /dev/null
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java
@@ -0,0 +1,65 @@
+package org.baeldung.equalshashcode.entities;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ComplexClass {
+
+ private List> genericList;
+ private Set integerSet;
+
+ public ComplexClass(ArrayList> genericArrayList, HashSet integerHashSet) {
+ super();
+ this.genericList = genericArrayList;
+ this.integerSet = integerHashSet;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((genericList == null) ? 0 : genericList.hashCode());
+ result = prime * result + ((integerSet == null) ? 0 : integerSet.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ComplexClass))
+ return false;
+ ComplexClass other = (ComplexClass) obj;
+ if (genericList == null) {
+ if (other.genericList != null)
+ return false;
+ } else if (!genericList.equals(other.genericList))
+ return false;
+ if (integerSet == null) {
+ if (other.integerSet != null)
+ return false;
+ } else if (!integerSet.equals(other.integerSet))
+ return false;
+ return true;
+ }
+
+ protected List> getGenericList() {
+ return genericList;
+ }
+
+ protected void setGenericArrayList(List> genericList) {
+ this.genericList = genericList;
+ }
+
+ protected Set getIntegerSet() {
+ return integerSet;
+ }
+
+ protected void setIntegerSet(Set integerSet) {
+ this.integerSet = integerSet;
+ }
+}
diff --git a/core-java/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java
new file mode 100644
index 0000000000..ebe005688c
--- /dev/null
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java
@@ -0,0 +1,54 @@
+package org.baeldung.equalshashcode.entities;
+
+public class PrimitiveClass {
+
+ private boolean primitiveBoolean;
+ private int primitiveInt;
+
+ public PrimitiveClass(boolean primitiveBoolean, int primitiveInt) {
+ super();
+ this.primitiveBoolean = primitiveBoolean;
+ this.primitiveInt = primitiveInt;
+ }
+
+ protected boolean isPrimitiveBoolean() {
+ return primitiveBoolean;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (primitiveBoolean ? 1231 : 1237);
+ result = prime * result + primitiveInt;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ PrimitiveClass other = (PrimitiveClass) obj;
+ if (primitiveBoolean != other.primitiveBoolean)
+ return false;
+ if (primitiveInt != other.primitiveInt)
+ return false;
+ return true;
+ }
+
+ protected void setPrimitiveBoolean(boolean primitiveBoolean) {
+ this.primitiveBoolean = primitiveBoolean;
+ }
+
+ protected int getPrimitiveInt() {
+ return primitiveInt;
+ }
+
+ protected void setPrimitiveInt(int primitiveInt) {
+ this.primitiveInt = primitiveInt;
+ }
+}
diff --git a/core-java/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
new file mode 100644
index 0000000000..1e1423f0b3
--- /dev/null
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
@@ -0,0 +1,58 @@
+package org.baeldung.equalshashcode.entities;
+
+public class Rectangle extends Shape {
+ private double width;
+ private double length;
+
+ public Rectangle(double width, double length) {
+ this.width = width;
+ this.length = length;
+ }
+
+ @Override
+ public double area() {
+ return width * length;
+ }
+
+ @Override
+ public double perimeter() {
+ return 2 * (width + length);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(length);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(width);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Rectangle other = (Rectangle) obj;
+ if (Double.doubleToLongBits(length) != Double.doubleToLongBits(other.length))
+ return false;
+ if (Double.doubleToLongBits(width) != Double.doubleToLongBits(other.width))
+ return false;
+ return true;
+ }
+
+ protected double getWidth() {
+ return width;
+ }
+
+ protected double getLength() {
+ return length;
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/org/baeldung/equalshashcode/entities/Shape.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Shape.java
new file mode 100644
index 0000000000..3bfc81da8f
--- /dev/null
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Shape.java
@@ -0,0 +1,7 @@
+package org.baeldung.equalshashcode.entities;
+
+public abstract class Shape {
+ public abstract double area();
+
+ public abstract double perimeter();
+}
diff --git a/core-java/src/main/java/org/baeldung/equalshashcode/entities/Square.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Square.java
new file mode 100644
index 0000000000..f11e34f0ba
--- /dev/null
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Square.java
@@ -0,0 +1,58 @@
+package org.baeldung.equalshashcode.entities;
+
+import java.awt.Color;
+
+public class Square extends Rectangle {
+
+ Color color;
+
+ public Square(double width, Color color) {
+ super(width, width);
+ this.color = color;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((color == null) ? 0 : color.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (!(obj instanceof Square)) {
+ return false;
+ }
+ Square other = (Square) obj;
+ if (color == null) {
+ if (other.color != null) {
+ return false;
+ }
+ } else if (!color.equals(other.color)) {
+ return false;
+ }
+ return true;
+ }
+
+ protected Color getColor() {
+ return color;
+ }
+
+ protected void setColor(Color color) {
+ this.color = color;
+ }
+
+}
diff --git a/core-java/src/main/resources/targetFile.tmp b/core-java/src/main/resources/targetFile.tmp
deleted file mode 100644
index 20f137b416..0000000000
--- a/core-java/src/main/resources/targetFile.tmp
+++ /dev/null
@@ -1,2 +0,0 @@
-line 1
-a second line
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/java/reflection/ReflectionTest.java b/core-java/src/test/java/com/baeldung/java/reflection/ReflectionTest.java
new file mode 100644
index 0000000000..a12a2f205f
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java/reflection/ReflectionTest.java
@@ -0,0 +1,326 @@
+package com.baeldung.java.reflection;
+
+import org.junit.Test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import static org.junit.Assert.*;
+
+public class ReflectionTest {
+
+ @Test
+ public void givenObject_whenGetsFieldNamesAtRuntime_thenCorrect() {
+ Object person = new Person();
+ Field[] fields = person.getClass().getDeclaredFields();
+
+ List actualFieldNames = getFieldNames(fields);
+
+ assertTrue(Arrays.asList("name", "age")
+ .containsAll(actualFieldNames));
+ }
+
+ @Test
+ public void givenObject_whenGetsClassName_thenCorrect() {
+ Object goat = new Goat("goat");
+ Class> clazz = goat.getClass();
+
+ assertEquals("Goat", clazz.getSimpleName());
+ assertEquals("com.baeldung.java.reflection.Goat", clazz.getName());
+ assertEquals("com.baeldung.java.reflection.Goat", clazz.getCanonicalName());
+ }
+
+ @Test
+ public void givenClassName_whenCreatesObject_thenCorrect()
+ throws ClassNotFoundException {
+ Class> clazz = Class.forName("com.baeldung.java.reflection.Goat");
+
+ assertEquals("Goat", clazz.getSimpleName());
+ assertEquals("com.baeldung.java.reflection.Goat", clazz.getName());
+ assertEquals("com.baeldung.java.reflection.Goat", clazz.getCanonicalName());
+ }
+
+ @Test
+ public void givenClass_whenRecognisesModifiers_thenCorrect()
+ throws ClassNotFoundException {
+ Class> goatClass = Class.forName("com.baeldung.java.reflection.Goat");
+ Class> animalClass = Class.forName("com.baeldung.java.reflection.Animal");
+ int goatMods = goatClass.getModifiers();
+ int animalMods = animalClass.getModifiers();
+
+ assertTrue(Modifier.isPublic(goatMods));
+ assertTrue(Modifier.isAbstract(animalMods));
+ assertTrue(Modifier.isPublic(animalMods));
+ }
+
+ @Test
+ public void givenClass_whenGetsPackageInfo_thenCorrect() {
+ Goat goat = new Goat("goat");
+ Class> goatClass = goat.getClass();
+ Package pkg = goatClass.getPackage();
+
+ assertEquals("com.baeldung.java.reflection", pkg.getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsSuperClass_thenCorrect() {
+ Goat goat = new Goat("goat");
+ String str = "any string";
+
+ Class> goatClass = goat.getClass();
+ Class> goatSuperClass = goatClass.getSuperclass();
+
+ assertEquals("Animal", goatSuperClass.getSimpleName());
+ assertEquals("Object", str.getClass().getSuperclass().getSimpleName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsImplementedInterfaces_thenCorrect()
+ throws ClassNotFoundException {
+ Class> goatClass = Class.forName("com.baeldung.java.reflection.Goat");
+ Class> animalClass = Class.forName("com.baeldung.java.reflection.Animal");
+ Class>[] goatInterfaces = goatClass.getInterfaces();
+ Class>[] animalInterfaces = animalClass.getInterfaces();
+
+ assertEquals(1, goatInterfaces.length);
+ assertEquals(1, animalInterfaces.length);
+ assertEquals("Locomotion", goatInterfaces[0].getSimpleName());
+ assertEquals("Eating", animalInterfaces[0].getSimpleName());
+ }
+
+ @Test
+ public void givenClass_whenGetsConstructor_thenCorrect()
+ throws ClassNotFoundException {
+ Class> goatClass = Class.forName("com.baeldung.java.reflection.Goat");
+ Constructor>[] constructors = goatClass.getConstructors();
+
+ assertEquals(1, constructors.length);
+ assertEquals("com.baeldung.java.reflection.Goat", constructors[0].getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsFields_thenCorrect()
+ throws ClassNotFoundException {
+ Class> animalClass = Class.forName("com.baeldung.java.reflection.Animal");
+ Field[] fields = animalClass.getDeclaredFields();
+
+ List actualFields = getFieldNames(fields);
+
+ assertEquals(2, actualFields.size());
+ assertTrue(actualFields.containsAll(Arrays.asList("name", "CATEGORY")));
+ }
+
+ @Test
+ public void givenClass_whenGetsMethods_thenCorrect()
+ throws ClassNotFoundException {
+ Class> animalClass = Class.forName("com.baeldung.java.reflection.Animal");
+ Method[] methods = animalClass.getDeclaredMethods();
+ List actualMethods = getMethodNames(methods);
+
+ assertEquals(4, actualMethods.size());
+ assertTrue(actualMethods.containsAll(Arrays.asList("getName",
+ "setName", "getSound")));
+ }
+
+ @Test
+ public void givenClass_whenGetsAllConstructors_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Constructor>[] constructors = birdClass.getConstructors();
+
+ assertEquals(3, constructors.length);
+ }
+
+ @Test
+ public void givenClass_whenGetsEachConstructorByParamTypes_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Constructor> cons1 = birdClass.getConstructor();
+ Constructor> cons2 = birdClass.getConstructor(String.class);
+ Constructor> cons3 = birdClass.getConstructor(String.class,
+ boolean.class);
+ }
+
+ @Test
+ public void givenClass_whenInstantiatesObjectsAtRuntime_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+
+ Constructor> cons1 = birdClass.getConstructor();
+ Constructor> cons2 = birdClass.getConstructor(String.class);
+ Constructor> cons3 = birdClass.getConstructor(String.class,
+ boolean.class);
+
+ Bird bird1 = (Bird) cons1.newInstance();
+ Bird bird2 = (Bird) cons2.newInstance("Weaver bird");
+ Bird bird3 = (Bird) cons3.newInstance("dove", true);
+
+ assertEquals("bird", bird1.getName());
+ assertEquals("Weaver bird", bird2.getName());
+ assertEquals("dove", bird3.getName());
+ assertFalse(bird1.walks());
+ assertTrue(bird3.walks());
+ }
+
+ @Test
+ public void givenClass_whenGetsPublicFields_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Field[] fields = birdClass.getFields();
+ assertEquals(1, fields.length);
+ assertEquals("CATEGORY", fields[0].getName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsPublicFieldByName_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Field field = birdClass.getField("CATEGORY");
+ assertEquals("CATEGORY", field.getName());
+
+ }
+
+ @Test
+ public void givenClass_whenGetsDeclaredFields_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Field[] fields = birdClass.getDeclaredFields();
+ assertEquals(1, fields.length);
+ assertEquals("walks", fields[0].getName());
+ }
+
+ @Test
+ public void givenClass_whenGetsFieldsByName_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Field field = birdClass.getDeclaredField("walks");
+ assertEquals("walks", field.getName());
+
+ }
+
+ @Test
+ public void givenClassField_whenGetsType_thenCorrect()
+ throws Exception {
+ Field field = Class.forName("com.baeldung.java.reflection.Bird")
+ .getDeclaredField("walks");
+ Class> fieldClass = field.getType();
+ assertEquals("boolean", fieldClass.getSimpleName());
+ }
+
+ @Test
+ public void givenClassField_whenSetsAndGetsValue_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Bird bird = (Bird) birdClass.newInstance();
+ Field field = birdClass.getDeclaredField("walks");
+ field.setAccessible(true);
+
+ assertFalse(field.getBoolean(bird));
+ assertFalse(bird.walks());
+
+ field.set(bird, true);
+
+ assertTrue(field.getBoolean(bird));
+ assertTrue(bird.walks());
+
+ }
+
+ @Test
+ public void givenClassField_whenGetsAndSetsWithNull_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Field field = birdClass.getField("CATEGORY");
+ field.setAccessible(true);
+
+ assertEquals("domestic", field.get(null));
+ }
+
+ @Test
+ public void givenClass_whenGetsAllPublicMethods_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Method[] methods = birdClass.getMethods();
+ List methodNames = getMethodNames(methods);
+
+ assertTrue(methodNames.containsAll(Arrays
+ .asList("equals", "notifyAll", "hashCode",
+ "walks", "eats", "toString")));
+
+ }
+
+ @Test
+ public void givenClass_whenGetsOnlyDeclaredMethods_thenCorrect()
+ throws ClassNotFoundException {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ List actualMethodNames = getMethodNames(birdClass.getDeclaredMethods());
+
+ List expectedMethodNames = Arrays.asList("setWalks", "walks", "getSound", "eats");
+
+ assertEquals(expectedMethodNames.size(), actualMethodNames.size());
+ assertTrue(expectedMethodNames.containsAll(actualMethodNames));
+ assertTrue(actualMethodNames.containsAll(expectedMethodNames));
+
+ }
+
+ @Test
+ public void givenMethodName_whenGetsMethod_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Method walksMethod = birdClass.getDeclaredMethod("walks");
+ Method setWalksMethod = birdClass.getDeclaredMethod("setWalks",
+ boolean.class);
+
+ assertFalse(walksMethod.isAccessible());
+ assertFalse(setWalksMethod.isAccessible());
+
+ walksMethod.setAccessible(true);
+ setWalksMethod.setAccessible(true);
+
+ assertTrue(walksMethod.isAccessible());
+ assertTrue(setWalksMethod.isAccessible());
+
+ }
+
+ @Test
+ public void givenMethod_whenInvokes_thenCorrect()
+ throws Exception {
+ Class> birdClass = Class.forName("com.baeldung.java.reflection.Bird");
+ Bird bird = (Bird) birdClass.newInstance();
+ Method setWalksMethod = birdClass.getDeclaredMethod("setWalks",
+ boolean.class);
+ Method walksMethod = birdClass.getDeclaredMethod("walks");
+ boolean walks = (boolean) walksMethod.invoke(bird);
+
+ assertFalse(walks);
+ assertFalse(bird.walks());
+
+ setWalksMethod.invoke(bird, true);
+ boolean walks2 = (boolean) walksMethod.invoke(bird);
+
+ assertTrue(walks2);
+ assertTrue(bird.walks());
+
+ }
+
+ private static List getFieldNames(Field[] fields) {
+ List fieldNames = new ArrayList<>();
+ for (Field field : fields)
+ fieldNames.add(field.getName());
+ return fieldNames;
+
+ }
+
+ private static List getMethodNames(Method[] methods) {
+ List methodNames = new ArrayList<>();
+ for (Method method : methods)
+ methodNames.add(method.getName());
+ return methodNames;
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/java/regex/RegexTest.java b/core-java/src/test/java/com/baeldung/java/regex/RegexTest.java
new file mode 100644
index 0000000000..257e486600
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java/regex/RegexTest.java
@@ -0,0 +1,503 @@
+package com.baeldung.java.regex;
+
+import static org.junit.Assert.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+public class RegexTest {
+ private static Pattern pattern;
+ private static Matcher matcher;
+
+ @Test
+ public void givenText_whenSimpleRegexMatches_thenCorrect() {
+ Result result = runTest("foo", "foo");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+
+ }
+
+ @Test
+ public void givenText_whenSimpleRegexMatchesTwice_thenCorrect() {
+ Result result = runTest("foo", "foofoo");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+
+ }
+
+ @Test
+ public void givenText_whenMatchesWithDotMetach_thenCorrect() {
+ Result result = runTest(".", "foo");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRepeatedText_whenMatchesOnceWithDotMetach_thenCorrect() {
+ Result result = runTest("foo.", "foofoo");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenORSet_whenMatchesAny_thenCorrect() {
+ Result result = runTest("[abc]", "b");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenORSet_whenMatchesAnyAndAll_thenCorrect() {
+ Result result = runTest("[abc]", "cab");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenORSet_whenMatchesAllCombinations_thenCorrect() {
+ Result result = runTest("[bcr]at", "bat cat rat");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenNORSet_whenMatchesNon_thenCorrect() {
+ Result result = runTest("[^abc]", "g");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenNORSet_whenMatchesAllExceptElements_thenCorrect() {
+ Result result = runTest("[^bcr]at", "sat mat eat");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenUpperCaseRange_whenMatchesUpperCase_thenCorrect() {
+ Result result = runTest("[A-Z]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenLowerCaseRange_whenMatchesLowerCase_thenCorrect() {
+ Result result = runTest("[a-z]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 26);
+ }
+
+ @Test
+ public void givenBothLowerAndUpperCaseRange_whenMatchesAllLetters_thenCorrect() {
+ Result result = runTest("[a-zA-Z]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 28);
+ }
+
+ @Test
+ public void givenNumberRange_whenMatchesAccurately_thenCorrect() {
+ Result result = runTest("[1-5]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenNumberRange_whenMatchesAccurately_thenCorrect2() {
+ Result result = runTest("[30-35]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenTwoSets_whenMatchesUnion_thenCorrect() {
+ Result result = runTest("[1-3[7-9]]", "123456789");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 6);
+ }
+
+ @Test
+ public void givenTwoSets_whenMatchesIntersection_thenCorrect() {
+ Result result = runTest("[1-6&&[3-9]]", "123456789");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 4);
+ }
+
+ @Test
+ public void givenSetWithSubtraction_whenMatchesAccurately_thenCorrect() {
+ Result result = runTest("[0-9&&[^2468]]", "123456789");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 5);
+ }
+
+ @Test
+ public void givenDigits_whenMatches_thenCorrect() {
+ Result result = runTest("\\d", "123");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenNonDigits_whenMatches_thenCorrect() {
+ Result result = runTest("\\D", "a6c");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenWhiteSpace_whenMatches_thenCorrect() {
+ Result result = runTest("\\s", "a c");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenNonWhiteSpace_whenMatches_thenCorrect() {
+ Result result = runTest("\\S", "a c");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenWordCharacter_whenMatches_thenCorrect() {
+ Result result = runTest("\\w", "hi!");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenNonWordCharacter_whenMatches_thenCorrect() {
+ Result result = runTest("\\W", "hi!");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenZeroOrOneQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("\\a?", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenZeroOrOneQuantifier_whenMatches_thenCorrect2() {
+ Result result = runTest("\\a{0,1}", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenZeroOrManyQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("\\a*", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenZeroOrManyQuantifier_whenMatches_thenCorrect2() {
+ Result result = runTest("\\a{0,}", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenOneOrManyQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("\\a+", "hi");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenOneOrManyQuantifier_whenMatches_thenCorrect2() {
+ Result result = runTest("\\a{1,}", "hi");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenBraceQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("a{3}", "aaaaaa");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenBraceQuantifier_whenFailsToMatch_thenCorrect() {
+ Result result = runTest("a{3}", "aa");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenBraceQuantifierWithRange_whenMatches_thenCorrect() {
+ Result result = runTest("a{2,3}", "aaaa");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenBraceQuantifierWithRange_whenMatchesLazily_thenCorrect() {
+ Result result = runTest("a{2,3}?", "aaaa");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatches_thenCorrect() {
+ Result result = runTest("(\\d\\d)", "12");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatches_thenCorrect2() {
+ Result result = runTest("(\\d\\d)", "1212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatches_thenCorrect3() {
+ Result result = runTest("(\\d\\d)(\\d\\d)", "1212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatchesWithBackReference_thenCorrect() {
+ Result result = runTest("(\\d\\d)\\1", "1212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatchesWithBackReference_thenCorrect2() {
+ Result result = runTest("(\\d\\d)\\1\\1\\1", "12121212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroupAndWrongInput_whenMatchFailsWithBackReference_thenCorrect() {
+ Result result = runTest("(\\d\\d)\\1", "1213");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtBeginning_thenCorrect() {
+ Result result = runTest("^dog", "dogs are friendly");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenTextAndWrongInput_whenMatchFailsAtBeginning_thenCorrect() {
+ Result result = runTest("^dog", "are dogs are friendly?");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtEnd_thenCorrect() {
+ Result result = runTest("dog$", "Man's best friend is a dog");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenTextAndWrongInput_whenMatchFailsAtEnd_thenCorrect() {
+ Result result = runTest("dog$", "is a dog man's best friend?");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtWordBoundary_thenCorrect() {
+ Result result = runTest("\\bdog\\b", "a dog is friendly");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtWordBoundary_thenCorrect2() {
+ Result result = runTest("\\bdog\\b", "dog is man's best friend");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenWrongText_whenMatchFailsAtWordBoundary_thenCorrect() {
+ Result result = runTest("\\bdog\\b", "snoop dogg is a rapper");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtWordAndNonBoundary_thenCorrect() {
+ Result result = runTest("\\bdog\\B", "snoop dogg is a rapper");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithoutCanonEq_whenMatchFailsOnEquivalentUnicode_thenCorrect() {
+ Result result = runTest("\u00E9", "\u0065\u0301");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithCanonEq_whenMatchesOnEquivalentUnicode_thenCorrect() {
+ Result result = runTest("\u00E9", "\u0065\u0301", Pattern.CANON_EQ);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithDefaultMatcher_whenMatchFailsOnDifferentCases_thenCorrect() {
+ Result result = runTest("dog", "This is a Dog");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithCaseInsensitiveMatcher_whenMatchesOnDifferentCases_thenCorrect() {
+ Result result = runTest("dog", "This is a Dog", Pattern.CASE_INSENSITIVE);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithEmbeddedCaseInsensitiveMatcher_whenMatchesOnDifferentCases_thenCorrect() {
+ Result result = runTest("(?i)dog", "This is a Dog");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithComments_whenMatchFailsWithoutFlag_thenCorrect() {
+ Result result = runTest("dog$ #check for word dog at end of text", "This is a dog");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithComments_whenMatchesWithFlag_thenCorrect() {
+ Result result = runTest("dog$ #check for word dog at end of text", "This is a dog", Pattern.COMMENTS);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithComments_whenMatchesWithEmbeddedFlag_thenCorrect() {
+ Result result = runTest("(?x)dog$ #check for word dog at end of text", "This is a dog");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithLineTerminator_whenMatchFails_thenCorrect() {
+ Pattern pattern = Pattern.compile("(.*)");
+ Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line");
+ matcher.find();
+ assertEquals("this is a text", matcher.group(1));
+ }
+
+ @Test
+ public void givenRegexWithLineTerminator_whenMatchesWithDotall_thenCorrect() {
+ Pattern pattern = Pattern.compile("(.*)", Pattern.DOTALL);
+ Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line");
+ matcher.find();
+ assertEquals("this is a text" + System.getProperty("line.separator") + " continued on another line", matcher.group(1));
+ }
+
+ @Test
+ public void givenRegexWithLineTerminator_whenMatchesWithEmbeddedDotall_thenCorrect() {
+ Pattern pattern = Pattern.compile("(?s)(.*)");
+ Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line");
+ matcher.find();
+ assertEquals("this is a text" + System.getProperty("line.separator") + " continued on another line", matcher.group(1));
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithoutLiteralFlag_thenCorrect() {
+ Result result = runTest("(.*)", "text");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchFailsWithLiteralFlag_thenCorrect() {
+ Result result = runTest("(.*)", "text", Pattern.LITERAL);
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithLiteralFlag_thenCorrect() {
+ Result result = runTest("(.*)", "text(.*)", Pattern.LITERAL);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchFailsWithoutMultilineFlag_thenCorrect() {
+ Result result = runTest("dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithMultilineFlag_thenCorrect() {
+ Result result = runTest("dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox", Pattern.MULTILINE);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithEmbeddedMultilineFlag_thenCorrect() {
+ Result result = runTest("(?m)dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenMatch_whenGetsIndices_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("This dog is mine");
+ matcher.find();
+ assertEquals(5, matcher.start());
+ assertEquals(8, matcher.end());
+ }
+
+ @Test
+ public void whenStudyMethodsWork_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dogs are friendly");
+ assertTrue(matcher.lookingAt());
+ assertFalse(matcher.matches());
+
+ }
+
+ @Test
+ public void whenMatchesStudyMethodWorks_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dog");
+ assertTrue(matcher.matches());
+
+ }
+
+ @Test
+ public void whenReplaceFirstWorks_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dogs are domestic animals, dogs are friendly");
+ String newStr = matcher.replaceFirst("cat");
+ assertEquals("cats are domestic animals, dogs are friendly", newStr);
+
+ }
+
+ @Test
+ public void whenReplaceAllWorks_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dogs are domestic animals, dogs are friendly");
+ String newStr = matcher.replaceAll("cat");
+ assertEquals("cats are domestic animals, cats are friendly", newStr);
+
+ }
+
+ public synchronized static Result runTest(String regex, String text) {
+ pattern = Pattern.compile(regex);
+ matcher = pattern.matcher(text);
+ Result result = new Result();
+ while (matcher.find())
+ result.setCount(result.getCount() + 1);
+ if (result.getCount() > 0)
+ result.setFound(true);
+ return result;
+ }
+
+ public synchronized static Result runTest(String regex, String text, int flags) {
+ pattern = Pattern.compile(regex, flags);
+ matcher = pattern.matcher(text);
+ Result result = new Result();
+ while (matcher.find())
+ result.setCount(result.getCount() + 1);
+ if (result.getCount() > 0)
+ result.setFound(true);
+ return result;
+ }
+}
diff --git a/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
new file mode 100644
index 0000000000..75d96e5989
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
@@ -0,0 +1,33 @@
+package org.baeldung.equalshashcode.entities;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ComplexClassTest {
+
+ @Test
+ public void testEqualsAndHashcodes() {
+
+ ArrayList strArrayList = new ArrayList();
+ strArrayList.add("abc");
+ strArrayList.add("def");
+ ComplexClass aObject = new ComplexClass(strArrayList, new HashSet(45, 67));
+ ComplexClass bObject = new ComplexClass(strArrayList, new HashSet(45, 67));
+
+ ArrayList strArrayListD = new ArrayList();
+ strArrayListD.add("lmn");
+ strArrayListD.add("pqr");
+ ComplexClass dObject = new ComplexClass(strArrayListD, new HashSet(45, 67));
+
+ Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
+
+ Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
+
+ Assert.assertFalse(aObject.equals(dObject));
+ Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
+ }
+
+}
diff --git a/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
new file mode 100644
index 0000000000..16f25ae021
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
@@ -0,0 +1,23 @@
+package org.baeldung.equalshashcode.entities;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PrimitiveClassTest {
+
+ @Test
+ public void testTwoEqualsObjects() {
+
+ PrimitiveClass aObject = new PrimitiveClass(false, 2);
+ PrimitiveClass bObject = new PrimitiveClass(false, 2);
+ PrimitiveClass dObject = new PrimitiveClass(true, 2);
+
+ Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
+
+ Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
+
+ Assert.assertFalse(aObject.equals(dObject));
+ Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
+ }
+
+}
diff --git a/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
new file mode 100644
index 0000000000..52d024a696
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
@@ -0,0 +1,26 @@
+package org.baeldung.equalshashcode.entities;
+
+import java.awt.Color;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SquareClassTest {
+
+ @Test
+ public void testEqualsAndHashcodes() {
+
+ Square aObject = new Square(10, Color.BLUE);
+ Square bObject = new Square(10, Color.BLUE);
+
+ Square dObject = new Square(20, Color.BLUE);
+
+ Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
+
+ Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
+
+ Assert.assertFalse(aObject.equals(dObject));
+ Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
+ }
+
+}
diff --git a/core-java/src/test/java/org/baeldung/java/collections/ArrayListTest.java b/core-java/src/test/java/org/baeldung/java/collections/ArrayListTest.java
new file mode 100644
index 0000000000..30b0111555
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/collections/ArrayListTest.java
@@ -0,0 +1,146 @@
+package org.baeldung.java.collections;
+
+import com.google.common.collect.Sets;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.stream.*;
+
+import static java.util.stream.Collectors.*;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.*;
+
+public class ArrayListTest {
+
+ private List stringsToSearch;
+
+ @Before
+ public void setUp() {
+ List list = LongStream.range(0, 16)
+ .boxed()
+ .map(Long::toHexString)
+ .collect(toCollection(ArrayList::new));
+ stringsToSearch = new ArrayList<>(list);
+ stringsToSearch.addAll(list);
+ }
+
+ @Test
+ public void givenNewArrayList_whenCheckCapacity_thenDefaultValue() {
+ List list = new ArrayList<>();
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ public void givenCollection_whenProvideItToArrayListCtor_thenArrayListIsPopulatedWithItsElements() {
+ Collection numbers =
+ IntStream.range(0, 10).boxed().collect(toSet());
+
+ List list = new ArrayList<>(numbers);
+ assertEquals(10, list.size());
+ assertTrue(numbers.containsAll(list));
+ }
+
+ @Test
+ public void givenElement_whenAddToArrayList_thenIsAdded() {
+ List list = new ArrayList<>();
+
+ list.add(1L);
+ list.add(2L);
+ list.add(1, 3L);
+
+ assertThat(Arrays.asList(1L, 3L, 2L), equalTo(list));
+ }
+
+ @Test
+ public void givenCollection_whenAddToArrayList_thenIsAdded() {
+ List list = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
+ LongStream.range(4, 10).boxed()
+ .collect(collectingAndThen(toCollection(ArrayList::new), ys -> list.addAll(0, ys)));
+
+ assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(list));
+ }
+
+ @Test
+ public void givenExistingElement_whenCallIndexOf_thenReturnCorrectIndex() {
+ assertEquals(10, stringsToSearch.indexOf("a"));
+ assertEquals(26, stringsToSearch.lastIndexOf("a"));
+ }
+
+ @Test
+ public void givenCondition_whenIterateArrayList_thenFindAllElementsSatisfyingCondition() {
+ Iterator it = stringsToSearch.iterator();
+ Set matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));
+
+ List result = new ArrayList<>();
+ while (it.hasNext()) {
+ String s = it.next();
+ if (matchingStrings.contains(s)) {
+ result.add(s);
+ }
+ }
+
+ assertEquals(6, result.size());
+ }
+
+ @Test
+ public void givenPredicate_whenIterateArrayList_thenFindAllElementsSatisfyingPredicate() {
+ Set matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));
+
+ List result = stringsToSearch
+ .stream()
+ .filter(matchingStrings::contains)
+ .collect(toCollection(ArrayList::new));
+
+ assertEquals(6, result.size());
+ }
+
+ @Test
+ public void givenSortedArray_whenUseBinarySearch_thenFindElement() {
+ List copy = new ArrayList<>(stringsToSearch);
+ Collections.sort(copy);
+ int index = Collections.binarySearch(copy, "f");
+ assertThat(index, not(equalTo(-1)));
+ }
+
+ @Test
+ public void givenIndex_whenRemove_thenCorrectElementRemoved() {
+ List list = IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new));
+ Collections.reverse(list);
+
+ list.remove(0);
+ assertThat(list.get(0), equalTo(8));
+
+ list.remove(Integer.valueOf(0));
+ assertFalse(list.contains(0));
+ }
+
+ @Test
+ public void givenListIterator_whenReverseTraversal_thenRetrieveElementsInOppositeOrder() {
+ List list = IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new));
+ ListIterator it = list.listIterator(list.size());
+ List result = new ArrayList<>(list.size());
+ while (it.hasPrevious()) {
+ result.add(it.previous());
+ }
+
+ Collections.reverse(list);
+ assertThat(result, equalTo(list));
+ }
+
+ @Test
+ public void givenCondition_whenIterateArrayList_thenRemoveAllElementsSatisfyingCondition() {
+ Set matchingStrings
+ = Sets.newHashSet("a", "b", "c", "d", "e", "f");
+
+ Iterator it = stringsToSearch.iterator();
+ while (it.hasNext()) {
+ if (matchingStrings.contains(it.next())) {
+ it.remove();
+ }
+ }
+
+ assertEquals(20, stringsToSearch.size());
+ }
+}
diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java
index 55a0904499..1a6ac5f8ce 100644
--- a/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java
+++ b/core-java/src/test/java/org/baeldung/java/io/JavaInputStreamToXUnitTest.java
@@ -19,6 +19,7 @@ import java.io.Reader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.nio.file.StandardCopyOption;
import java.util.Scanner;
import org.apache.commons.io.FileUtils;
@@ -191,6 +192,16 @@ public class JavaInputStreamToXUnitTest {
IOUtils.closeQuietly(outStream);
}
+ @Test
+ public final void givenUsingPlainJava8_whenConvertingAnInProgressInputStreamToAFile_thenCorrect() throws IOException {
+ final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt"));
+ final File targetFile = new File("src/main/resources/targetFile.tmp");
+
+ java.nio.file.Files.copy(initialStream, targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
+ IOUtils.closeQuietly(initialStream);
+ }
+
@Test
public final void givenUsingGuava_whenConvertingAnInputStreamToAFile_thenCorrect() throws IOException {
final InputStream initialStream = new FileInputStream(new File("src/main/resources/sample.txt"));
diff --git a/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java b/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java
index 7a4c7366eb..3c574f1e5c 100644
--- a/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java
+++ b/core-java/src/test/java/org/baeldung/java/io/JavaReaderToXUnitTest.java
@@ -1,5 +1,8 @@
package org.baeldung.java.io;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
@@ -187,10 +190,24 @@ public class JavaReaderToXUnitTest {
targetStream.close();
}
+ @Test
+ public void givenUsingCommonsIO_whenConvertingReaderIntoInputStream_thenCorrect() throws IOException {
+ String initialString = "With Commons IO";
+ final Reader initialReader = new StringReader(initialString);
+
+ final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader));
+
+ final String finalString = IOUtils.toString(targetStream);
+ assertThat(finalString, equalTo(initialString));
+
+ initialReader.close();
+ targetStream.close();
+ }
+
// tests - Reader to InputStream with encoding
@Test
- public void givenUsingPlainJava_whenConvertingReaderIntoInputStreamWithCharset_thenCorrect() throws IOException {
+ public void givenUsingPlainJava_whenConvertingReaderIntoInputStreamWithCharset() throws IOException {
final Reader initialReader = new StringReader("With Java");
final char[] charBuffer = new char[8 * 1024];
@@ -225,4 +242,17 @@ public class JavaReaderToXUnitTest {
targetStream.close();
}
+ @Test
+ public void givenUsingCommonsIO_whenConvertingReaderIntoInputStreamWithEncoding_thenCorrect() throws IOException {
+ String initialString = "With Commons IO";
+ final Reader initialReader = new StringReader(initialString);
+ final InputStream targetStream = IOUtils.toInputStream(IOUtils.toString(initialReader), Charsets.UTF_8);
+
+ String finalString = IOUtils.toString(targetStream, Charsets.UTF_8);
+ assertThat(finalString, equalTo(initialString));
+
+ initialReader.close();
+ targetStream.close();
+ }
+
}
diff --git a/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java
new file mode 100644
index 0000000000..83f1fb33b6
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java
@@ -0,0 +1,90 @@
+package org.baeldung.java.md5;
+
+import static org.junit.Assert.*;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class JavaMD5Test {
+
+
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+
+
+ @Test
+ public void givenPassword_whenHashing_thenVerifying() throws NoSuchAlgorithmException {
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(password.getBytes());
+ byte[] digest = md.digest();
+ String myHash = DatatypeConverter.printHexBinary(digest).toUpperCase();
+
+ assertThat(myHash.equals(hash)).isTrue();
+ }
+
+ @Test
+ public void givenFile_generatingChecksum_thenVerifying() throws NoSuchAlgorithmException, IOException {
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(Files.readAllBytes(Paths.get(filename)));
+ byte[] digest = md.digest();
+ String myChecksum = DatatypeConverter
+ .printHexBinary(digest).toUpperCase();
+
+ assertThat(myChecksum.equals(checksum)).isTrue();
+ }
+
+ @Test
+ public void givenPassword_whenHashingUsingCommons_thenVerifying() {
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+ String md5Hex = DigestUtils
+ .md5Hex(password).toUpperCase();
+
+ assertThat(md5Hex.equals(hash)).isTrue();
+ }
+
+
+ @Test
+ public void givenFile_whenChecksumUsingGuava_thenVerifying() throws IOException {
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ HashCode hash = com.google.common.io.Files
+ .hash(new File(filename), Hashing.md5());
+ String myChecksum = hash.toString()
+ .toUpperCase();
+
+ assertThat(myChecksum.equals(checksum)).isTrue();
+ }
+
+
+}
diff --git a/core-java/src/test/java/org/baeldung/java/shell/JavaProcessUnitTest.java b/core-java/src/test/java/org/baeldung/java/shell/JavaProcessUnitTest.java
new file mode 100644
index 0000000000..2c330c513d
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/shell/JavaProcessUnitTest.java
@@ -0,0 +1,66 @@
+package org.baeldung.java.shell;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.*;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+
+public class JavaProcessUnitTest {
+ private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().startsWith("windows");
+
+ private static class StreamGobbler implements Runnable {
+ private InputStream inputStream;
+ private Consumer consumer;
+
+ public StreamGobbler(InputStream inputStream, Consumer consumer) {
+ this.inputStream = inputStream;
+ this.consumer = consumer;
+ }
+
+ @Override
+ public void run() {
+ new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
+ }
+ }
+
+ private Consumer consumer = new Consumer() {
+ @Override
+ public void accept(String s) {
+ Assert.assertNotNull(s);
+ }
+ };
+
+ private String homeDirectory = System.getProperty("user.home");
+
+ @Test
+ public void givenProcess_whenCreatingViaRuntime_shouldSucceed() throws Exception {
+ Process process;
+ if (IS_WINDOWS) {
+ process = Runtime.getRuntime().exec(String.format("cmd.exe /c dir %s", homeDirectory));
+ } else {
+ process = Runtime.getRuntime().exec(String.format("sh -c ls %s", homeDirectory));
+ }
+ StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
+ Executors.newSingleThreadExecutor().submit(streamGobbler);
+ int exitCode = process.waitFor();
+ Assert.assertEquals(0, exitCode);
+ }
+
+ @Test
+ public void givenProcess_whenCreatingViaProcessBuilder_shouldSucceed() throws Exception {
+ ProcessBuilder builder = new ProcessBuilder();
+ if (IS_WINDOWS) {
+ builder.command("cmd.exe", "/c", "dir");
+ } else {
+ builder.command("sh", "-c", "ls");
+ }
+ builder.directory(new File(homeDirectory));
+ Process process = builder.start();
+ StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), consumer);
+ Executors.newSingleThreadExecutor().submit(streamGobbler);
+ int exitCode = process.waitFor();
+ Assert.assertEquals(0, exitCode);
+ }
+}
diff --git a/deltaspike/.gitignore b/deltaspike/.gitignore
new file mode 100644
index 0000000000..aa121e866e
--- /dev/null
+++ b/deltaspike/.gitignore
@@ -0,0 +1,3 @@
+/.idea
+baeldung-jee7-seed.iml
+/target
diff --git a/deltaspike/pom.xml b/deltaspike/pom.xml
new file mode 100644
index 0000000000..22cf8f935c
--- /dev/null
+++ b/deltaspike/pom.xml
@@ -0,0 +1,301 @@
+
+
+ 4.0.0
+ com.baeldung
+ deltaspike
+ 1.0
+ war
+ deltaspike
+ A starter Java EE 7 webapp which uses DeltaSpike
+
+ http://wildfly.org
+
+
+ Apache License, Version 2.0
+ repo
+ http://www.apache.org/licenses/LICENSE-2.0.html
+
+
+
+
+
+
+ UTF-8
+
+
+ 1.0.2.Final
+
+
+ 8.2.1.Final
+
+
+ 3.1
+ 2.16
+ 2.5
+
+
+ 1.7
+ 1.7
+
+
+
+
+
+
+
+ org.wildfly.bom
+ jboss-javaee-7.0-with-tools
+ ${version.jboss.bom}
+ pom
+ import
+
+
+ org.wildfly.bom
+ jboss-javaee-7.0-with-hibernate
+ ${version.jboss.bom}
+ pom
+ import
+
+
+
+
+
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ provided
+
+
+
+
+ org.jboss.spec.javax.annotation
+ jboss-annotations-api_1.2_spec
+ provided
+
+
+
+
+ org.jboss.resteasy
+ jaxrs-api
+ provided
+
+
+
+
+ org.hibernate.javax.persistence
+ hibernate-jpa-2.1-api
+ provided
+
+
+
+
+ org.jboss.spec.javax.ejb
+ jboss-ejb-api_3.2_spec
+ provided
+
+
+
+
+
+
+ org.hibernate
+ hibernate-validator
+ provided
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+
+
+ org.jboss.spec.javax.faces
+ jboss-jsf-api_2.2_spec
+ provided
+
+
+
+
+
+
+ org.hibernate
+ hibernate-jpamodelgen
+ provided
+
+
+
+
+ org.hibernate
+ hibernate-validator-annotation-processor
+ provided
+
+
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+ org.jboss.arquillian.junit
+ arquillian-junit-container
+ test
+
+
+
+ org.jboss.arquillian.protocol
+ arquillian-protocol-servlet
+ test
+
+
+
+ org.jboss.shrinkwrap.resolver
+ shrinkwrap-resolver-impl-maven
+ test
+
+
+
+ org.apache.deltaspike.modules
+ deltaspike-data-module-api
+ 1.7.1
+ compile
+
+
+
+ org.apache.deltaspike.modules
+ deltaspike-data-module-impl
+ 1.7.1
+ runtime
+
+
+
+
+ com.mysema.querydsl
+ querydsl-apt
+ 3.7.4
+ provided
+
+
+
+ com.mysema.querydsl
+ querydsl-jpa
+ 3.7.4
+
+
+
+ org.slf4j
+ slf4j-log4j12
+ 1.6.1
+
+
+
+
+
+ ${project.artifactId}
+
+
+ maven-war-plugin
+ ${version.war.plugin}
+
+
+ false
+
+
+
+ com.mysema.maven
+ apt-maven-plugin
+ 1.0.9
+
+
+
+ process
+
+
+ target/generated-sources/java
+ com.mysema.query.apt.jpa.JPAAnnotationProcessor
+
+
+
+
+
+
+
+ org.wildfly.plugins
+ wildfly-maven-plugin
+ ${version.wildfly.maven.plugin}
+
+
+
+
+
+
+
+
+ default
+
+ true
+
+
+
+
+ maven-surefire-plugin
+ ${version.surefire.plugin}
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ arq-wildfly-managed
+
+
+ org.wildfly
+ wildfly-arquillian-container-managed
+ test
+
+
+
+
+
diff --git a/deltaspike/src/main/java/baeldung/controller/MemberController.java b/deltaspike/src/main/java/baeldung/controller/MemberController.java
new file mode 100644
index 0000000000..7a9e9800f4
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/controller/MemberController.java
@@ -0,0 +1,84 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.controller;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.inject.Model;
+import javax.enterprise.inject.Produces;
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import baeldung.model.Member;
+import baeldung.service.MemberRegistration;
+
+// The @Model stereotype is a convenience mechanism to make this a request-scoped bean that has an
+// EL name
+// Read more about the @Model stereotype in this FAQ:
+// http://www.cdi-spec.org/faq/#accordion6
+@Model
+public class MemberController {
+
+ @Inject
+ private FacesContext facesContext;
+
+ @Inject
+ private MemberRegistration memberRegistration;
+
+ @Produces
+ @Named
+ private Member newMember;
+
+ @PostConstruct
+ public void initNewMember() {
+ newMember = new Member();
+ }
+
+ public void register() throws Exception {
+ try {
+ memberRegistration.register(newMember);
+ FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_INFO, "Registered!", "Registration successful");
+ facesContext.addMessage(null, m);
+ initNewMember();
+ } catch (Exception e) {
+ String errorMessage = getRootErrorMessage(e);
+ FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, "Registration unsuccessful");
+ facesContext.addMessage(null, m);
+ }
+ }
+
+ private String getRootErrorMessage(Exception e) {
+ // Default to general error message that registration failed.
+ String errorMessage = "Registration failed. See server log for more information";
+ if (e == null) {
+ // This shouldn't happen, but return the default messages
+ return errorMessage;
+ }
+
+ // Start with the exception and recurse to find the root cause
+ Throwable t = e;
+ while (t != null) {
+ // Get the message from the Throwable class instance
+ errorMessage = t.getLocalizedMessage();
+ t = t.getCause();
+ }
+ // This is the root cause message
+ return errorMessage;
+ }
+
+}
diff --git a/deltaspike/src/main/java/baeldung/data/EntityManagerProducer.java b/deltaspike/src/main/java/baeldung/data/EntityManagerProducer.java
new file mode 100644
index 0000000000..9189dbba74
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/EntityManagerProducer.java
@@ -0,0 +1,29 @@
+package baeldung.data;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnit;
+
+@ApplicationScoped
+public class EntityManagerProducer {
+ @PersistenceUnit(unitName = "primary")
+ private EntityManagerFactory entityManagerFactory;
+
+ @Produces
+ @Default
+ @RequestScoped
+ public EntityManager create() {
+ return this.entityManagerFactory.createEntityManager();
+ }
+
+ public void dispose(@Disposes @Default EntityManager entityManager) {
+ if (entityManager.isOpen()) {
+ entityManager.close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/deltaspike/src/main/java/baeldung/data/MemberListProducer.java b/deltaspike/src/main/java/baeldung/data/MemberListProducer.java
new file mode 100644
index 0000000000..c1f5fda31d
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/MemberListProducer.java
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.data;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.event.Reception;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.List;
+
+import baeldung.model.Member;
+
+@RequestScoped
+public class MemberListProducer {
+
+ @Inject
+ private MemberRepository memberRepository;
+
+ private List members;
+
+ // @Named provides access the return value via the EL variable name "members" in the UI (e.g.
+ // Facelets or JSP view)
+ @Produces
+ @Named
+ public List getMembers() {
+ return members;
+ }
+
+ public void onMemberListChanged(@Observes(notifyObserver = Reception.IF_EXISTS) final Member member) {
+ retrieveAllMembersOrderedByName();
+ }
+
+ @PostConstruct
+ public void retrieveAllMembersOrderedByName() {
+ members = memberRepository.findAllOrderedByNameWithQueryDSL();
+ }
+}
diff --git a/deltaspike/src/main/java/baeldung/data/MemberRepository.java b/deltaspike/src/main/java/baeldung/data/MemberRepository.java
new file mode 100644
index 0000000000..56a4a4e634
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/MemberRepository.java
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.data;
+
+import baeldung.model.Member;
+import baeldung.model.QMember;
+import org.apache.deltaspike.data.api.*;
+
+import java.util.List;
+
+@Repository
+@EntityManagerConfig(entityManagerResolver = SecondaryEntityManagerResolver.class)
+public abstract class MemberRepository extends AbstractEntityRepository implements QueryDslSupport {
+
+ public abstract Member findById(Long id);
+
+ public abstract Member findByEmail(String email);
+
+ @Query("from Member m order by m.name")
+ public abstract List findAllOrderedByName();
+
+ public List findAllOrderedByNameWithQueryDSL() {
+ final QMember member = QMember.member;
+ return jpaQuery()
+ .from(member)
+ .orderBy(member.email.asc())
+ .list(member);
+ }
+}
diff --git a/deltaspike/src/main/java/baeldung/data/QueryDslRepositoryExtension.java b/deltaspike/src/main/java/baeldung/data/QueryDslRepositoryExtension.java
new file mode 100644
index 0000000000..8cb00958ab
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/QueryDslRepositoryExtension.java
@@ -0,0 +1,18 @@
+package baeldung.data;
+
+import com.mysema.query.jpa.impl.JPAQuery;
+import org.apache.deltaspike.data.spi.DelegateQueryHandler;
+import org.apache.deltaspike.data.spi.QueryInvocationContext;
+
+import javax.inject.Inject;
+
+public class QueryDslRepositoryExtension implements QueryDslSupport, DelegateQueryHandler {
+
+ @Inject
+ private QueryInvocationContext context;
+
+ @Override
+ public JPAQuery jpaQuery() {
+ return new JPAQuery(context.getEntityManager());
+ }
+}
diff --git a/deltaspike/src/main/java/baeldung/data/QueryDslSupport.java b/deltaspike/src/main/java/baeldung/data/QueryDslSupport.java
new file mode 100644
index 0000000000..72c33cf1b6
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/QueryDslSupport.java
@@ -0,0 +1,7 @@
+package baeldung.data;
+
+import com.mysema.query.jpa.impl.JPAQuery;
+
+public interface QueryDslSupport {
+ JPAQuery jpaQuery();
+}
diff --git a/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerProducer.java b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerProducer.java
new file mode 100644
index 0000000000..41d30d9018
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerProducer.java
@@ -0,0 +1,30 @@
+package baeldung.data;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.Produces;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnit;
+
+@ApplicationScoped
+public class SecondaryEntityManagerProducer {
+ @PersistenceUnit(unitName = "secondary")
+ private EntityManagerFactory entityManagerFactory;
+
+ @Produces
+ @Default
+ @RequestScoped
+ @SecondaryPersistenceUnit
+ public EntityManager create() {
+ return this.entityManagerFactory.createEntityManager();
+ }
+
+ public void dispose(@Disposes @Default EntityManager entityManager) {
+ if (entityManager.isOpen()) {
+ entityManager.close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerResolver.java b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerResolver.java
new file mode 100644
index 0000000000..7faaa1ac49
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/SecondaryEntityManagerResolver.java
@@ -0,0 +1,18 @@
+package baeldung.data;
+
+import org.apache.deltaspike.data.api.EntityManagerResolver;
+
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+
+public class SecondaryEntityManagerResolver implements EntityManagerResolver {
+
+ @Inject
+ @SecondaryPersistenceUnit
+ private EntityManager entityManager;
+
+ @Override
+ public EntityManager resolveEntityManager() {
+ return entityManager;
+ }
+}
diff --git a/deltaspike/src/main/java/baeldung/data/SecondaryPersistenceUnit.java b/deltaspike/src/main/java/baeldung/data/SecondaryPersistenceUnit.java
new file mode 100644
index 0000000000..e60d0aff05
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/data/SecondaryPersistenceUnit.java
@@ -0,0 +1,12 @@
+package baeldung.data;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Qualifier
+public @interface SecondaryPersistenceUnit {
+}
diff --git a/deltaspike/src/main/java/baeldung/model/Member.java b/deltaspike/src/main/java/baeldung/model/Member.java
new file mode 100644
index 0000000000..e178dcf63a
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/model/Member.java
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.hibernate.validator.constraints.Email;
+import org.hibernate.validator.constraints.NotEmpty;
+
+@SuppressWarnings("serial")
+@Entity
+@XmlRootElement
+@Table(uniqueConstraints = @UniqueConstraint(columnNames = "email"))
+public class Member implements Serializable {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ @NotNull
+ @Size(min = 1, max = 25)
+ @Pattern(regexp = "[^0-9]*", message = "Must not contain numbers")
+ private String name;
+
+ @NotNull
+ @NotEmpty
+ @Email
+ private String email;
+
+ @NotNull
+ @Size(min = 10, max = 12)
+ @Digits(fraction = 0, integer = 12)
+ @Column(name = "phone_number")
+ private String phoneNumber;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ public void setPhoneNumber(String phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+}
diff --git a/deltaspike/src/main/java/baeldung/rest/JaxRsActivator.java b/deltaspike/src/main/java/baeldung/rest/JaxRsActivator.java
new file mode 100644
index 0000000000..9357ae0ea6
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/rest/JaxRsActivator.java
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.rest;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+/**
+ * A class extending {@link Application} and annotated with @ApplicationPath is the Java EE 7 "no XML" approach to activating
+ * JAX-RS.
+ *
+ *
+ * Resources are served relative to the servlet path specified in the {@link ApplicationPath} annotation.
+ *
+ */
+@ApplicationPath("/rest")
+public class JaxRsActivator extends Application {
+ /* class body intentionally left blank */
+}
diff --git a/deltaspike/src/main/java/baeldung/rest/MemberResourceRESTService.java b/deltaspike/src/main/java/baeldung/rest/MemberResourceRESTService.java
new file mode 100644
index 0000000000..5a09e45591
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/rest/MemberResourceRESTService.java
@@ -0,0 +1,185 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.rest;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.persistence.NoResultException;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import baeldung.data.MemberRepository;
+import baeldung.model.Member;
+import baeldung.service.MemberRegistration;
+
+/**
+ * JAX-RS Example
+ *
+ * This class produces a RESTful service to read/write the contents of the members table.
+ */
+@Path("/members")
+@RequestScoped
+public class MemberResourceRESTService {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private Validator validator;
+
+ @Inject
+ private MemberRepository repository;
+
+ @Inject
+ MemberRegistration registration;
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public List listAllMembers() {
+ return repository.findAllOrderedByName();
+ }
+
+ @GET
+ @Path("/{id:[0-9][0-9]*}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Member lookupMemberById(@PathParam("id") long id) {
+ Member member = repository.findById(id);
+ if (member == null) {
+ throw new WebApplicationException(Response.Status.NOT_FOUND);
+ }
+ return member;
+ }
+
+ /**
+ * Creates a new member from the values provided. Performs validation, and will return a JAX-RS response with either 200 ok,
+ * or with a map of fields, and related errors.
+ */
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response createMember(Member member) {
+
+ Response.ResponseBuilder builder = null;
+
+ try {
+ // Validates member using bean validation
+ validateMember(member);
+
+ registration.register(member);
+
+ // Create an "ok" response
+ builder = Response.ok();
+ } catch (ConstraintViolationException ce) {
+ // Handle bean validation issues
+ builder = createViolationResponse(ce.getConstraintViolations());
+ } catch (ValidationException e) {
+ // Handle the unique constrain violation
+ Map responseObj = new HashMap<>();
+ responseObj.put("email", "Email taken");
+ builder = Response.status(Response.Status.CONFLICT).entity(responseObj);
+ } catch (Exception e) {
+ // Handle generic exceptions
+ Map responseObj = new HashMap<>();
+ responseObj.put("error", e.getMessage());
+ builder = Response.status(Response.Status.BAD_REQUEST).entity(responseObj);
+ }
+
+ return builder.build();
+ }
+
+ /**
+ *
+ * Validates the given Member variable and throws validation exceptions based on the type of error. If the error is standard
+ * bean validation errors then it will throw a ConstraintValidationException with the set of the constraints violated.
+ *
+ *
+ * If the error is caused because an existing member with the same email is registered it throws a regular validation
+ * exception so that it can be interpreted separately.
+ *
+ *
+ * @param member Member to be validated
+ * @throws ConstraintViolationException If Bean Validation errors exist
+ * @throws ValidationException If member with the same email already exists
+ */
+ private void validateMember(Member member) throws ConstraintViolationException, ValidationException {
+ // Create a bean validator and check for issues.
+ Set> violations = validator.validate(member);
+
+ if (!violations.isEmpty()) {
+ throw new ConstraintViolationException(new HashSet>(violations));
+ }
+
+ // Check the uniqueness of the email address
+ if (emailAlreadyExists(member.getEmail())) {
+ throw new ValidationException("Unique Email Violation");
+ }
+ }
+
+ /**
+ * Creates a JAX-RS "Bad Request" response including a map of all violation fields, and their message. This can then be used
+ * by clients to show violations.
+ *
+ * @param violations A set of violations that needs to be reported
+ * @return JAX-RS response containing all violations
+ */
+ private Response.ResponseBuilder createViolationResponse(Set> violations) {
+ log.fine("Validation completed. violations found: " + violations.size());
+
+ Map responseObj = new HashMap<>();
+
+ for (ConstraintViolation> violation : violations) {
+ responseObj.put(violation.getPropertyPath().toString(), violation.getMessage());
+ }
+
+ return Response.status(Response.Status.BAD_REQUEST).entity(responseObj);
+ }
+
+ /**
+ * Checks if a member with the same email address is already registered. This is the only way to easily capture the
+ * "@UniqueConstraint(columnNames = "email")" constraint from the Member class.
+ *
+ * @param email The email to check
+ * @return True if the email already exists, and false otherwise
+ */
+ public boolean emailAlreadyExists(String email) {
+ Member member = null;
+ try {
+ member = repository.findByEmail(email);
+ } catch (NoResultException e) {
+ // ignore
+ }
+ return member != null;
+ }
+}
diff --git a/deltaspike/src/main/java/baeldung/service/MemberRegistration.java b/deltaspike/src/main/java/baeldung/service/MemberRegistration.java
new file mode 100644
index 0000000000..ec65471622
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/service/MemberRegistration.java
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.service;
+
+import baeldung.data.MemberRepository;
+import baeldung.data.SecondaryPersistenceUnit;
+import baeldung.model.Member;
+import baeldung.model.QMember;
+
+import javax.ejb.Stateless;
+import javax.enterprise.event.Event;
+import javax.enterprise.inject.Default;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+@Stateless
+public class MemberRegistration {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private MemberRepository repository;
+
+ @Inject
+ private Event memberEventSrc;
+
+ @Inject
+ private Validator validator;
+
+ private void validateMember(Member member) throws ConstraintViolationException, ValidationException {
+ // Create a bean validator and check for issues.
+ Set> violations = validator.validate(member);
+
+ if (!violations.isEmpty()) {
+ throw new ConstraintViolationException(new HashSet>(violations));
+ }
+
+ // Check the uniqueness of the email address
+ if (emailAlreadyExists(member.getEmail())) {
+ throw new ValidationException("Unique Email Violation");
+ }
+ }
+
+
+ public void register(Member member) throws Exception {
+ log.info("Registering " + member.getName());
+ validateMember(member);
+ repository.save(member);
+ memberEventSrc.fire(member);
+ }
+
+ public boolean emailAlreadyExists(String email) {
+ Member member = null;
+ try {
+ member = repository.findByEmail(email);
+ } catch (NoResultException e) {
+ // ignore
+ }
+ return member != null;
+ }
+
+}
diff --git a/deltaspike/src/main/java/baeldung/util/Resources.java b/deltaspike/src/main/java/baeldung/util/Resources.java
new file mode 100644
index 0000000000..2cc1f235d7
--- /dev/null
+++ b/deltaspike/src/main/java/baeldung/util/Resources.java
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+ * contributors by the @authors tag. See the copyright.txt in the
+ * distribution for a full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package baeldung.util;
+
+import java.util.logging.Logger;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.faces.context.FacesContext;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * This class uses CDI to alias Java EE resources, such as the persistence context, to CDI beans
+ *
+ *
+ * Example injection on a managed bean field:
+ *
+ *
+ *
+ * @Inject
+ * private EntityManager em;
+ *
+ */
+public class Resources {
+
+ @Produces
+ public Logger produceLog(InjectionPoint injectionPoint) {
+ return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
+ }
+
+ @Produces
+ @RequestScoped
+ public FacesContext produceFacesContext() {
+ return FacesContext.getCurrentInstance();
+ }
+
+}
diff --git a/deltaspike/src/main/resources/META-INF/apache-deltaspike.properties b/deltaspike/src/main/resources/META-INF/apache-deltaspike.properties
new file mode 100644
index 0000000000..a861ad729a
--- /dev/null
+++ b/deltaspike/src/main/resources/META-INF/apache-deltaspike.properties
@@ -0,0 +1 @@
+globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy
diff --git a/deltaspike/src/main/resources/META-INF/persistence.xml b/deltaspike/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000000..b68c2c1bb1
--- /dev/null
+++ b/deltaspike/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,21 @@
+
+
+
+ java:jboss/datasources/baeldung-jee7-seedDS
+
+
+
+
+
+
+ java:jboss/datasources/baeldung-jee7-seed-secondaryDS
+
+
+
+
+
+
diff --git a/deltaspike/src/main/resources/import.sql b/deltaspike/src/main/resources/import.sql
new file mode 100644
index 0000000000..154f4e9923
--- /dev/null
+++ b/deltaspike/src/main/resources/import.sql
@@ -0,0 +1,19 @@
+--
+-- JBoss, Home of Professional Open Source
+-- Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
+-- contributors by the @authors tag. See the copyright.txt in the
+-- distribution for a full listing of individual contributors.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+-- http://www.apache.org/licenses/LICENSE-2.0
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- You can use this file to load seed data into the database using SQL statements
+insert into Member (id, name, email, phone_number) values (0, 'John Smith', 'john.smith@mailinator.com', '2125551212')
diff --git a/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-ds.xml b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-ds.xml
new file mode 100644
index 0000000000..1a8e350667
--- /dev/null
+++ b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-ds.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ jdbc:h2:mem:baeldung-jee7-seed;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
+ h2
+
+ sa
+ sa
+
+
+
+
diff --git a/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-secondary-ds.xml b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-secondary-ds.xml
new file mode 100644
index 0000000000..c4c9afb2e0
--- /dev/null
+++ b/deltaspike/src/main/webapp/WEB-INF/baeldung-jee7-seed-secondary-ds.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ jdbc:h2:mem:baeldung-jee7-seed;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
+ h2
+
+ sa
+ sa
+
+
+
+
diff --git a/deltaspike/src/main/webapp/WEB-INF/beans.xml b/deltaspike/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000000..0090177eb7
--- /dev/null
+++ b/deltaspike/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/deltaspike/src/main/webapp/WEB-INF/faces-config.xml b/deltaspike/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 0000000000..26cf98b669
--- /dev/null
+++ b/deltaspike/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/deltaspike/src/main/webapp/WEB-INF/templates/default.xhtml b/deltaspike/src/main/webapp/WEB-INF/templates/default.xhtml
new file mode 100644
index 0000000000..2f001f8626
--- /dev/null
+++ b/deltaspike/src/main/webapp/WEB-INF/templates/default.xhtml
@@ -0,0 +1,55 @@
+
+
+
+
+ baeldung-jee7-seed
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-thymeleaf/src/main/webapp/WEB-INF/views/listStudents.html b/spring-thymeleaf/src/main/webapp/WEB-INF/views/listStudents.html
index c25de9eb17..a894e41e88 100644
--- a/spring-thymeleaf/src/main/webapp/WEB-INF/views/listStudents.html
+++ b/spring-thymeleaf/src/main/webapp/WEB-INF/views/listStudents.html
@@ -4,6 +4,15 @@
Student List
+
+