diff --git a/apache-cxf/cxf-introduction/pom.xml b/apache-cxf/cxf-introduction/pom.xml
index e28039c1af..232a4f0089 100644
--- a/apache-cxf/cxf-introduction/pom.xml
+++ b/apache-cxf/cxf-introduction/pom.xml
@@ -1,53 +1,47 @@
- 4.0.0
- cxf-introduction
-
- com.baeldung
- apache-cxf
- 0.0.1-SNAPSHOT
-
-
- true
- 3.1.6
-
-
-
- org.apache.cxf
- cxf-rt-frontend-jaxws
- ${cxf.version}
-
-
- org.apache.cxf
- cxf-rt-transports-http-jetty
- ${cxf.version}
-
-
-
-
- server
-
- test
-
-
- org.codehaus.mojo
- exec-maven-plugin
-
-
- test
-
- java
-
-
- com.baeldung.cxf.introduction.Server
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ 4.0.0
+ cxf-introduction
+
+ com.baeldung
+ apache-cxf
+ 0.0.1-SNAPSHOT
+
+
+ 3.1.6
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+ com.baeldung.cxf.introduction.Server
+
+
+
+ maven-surefire-plugin
+ 2.19.1
+
+
+ **/StudentTest.java
+
+
+
+
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+ ${cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-transports-http-jetty
+ ${cxf.version}
+
+
+
diff --git a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java b/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java
index 58caa9087e..0e5af60b9d 100644
--- a/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java
+++ b/apache-cxf/cxf-introduction/src/main/java/com/baeldung/cxf/introduction/Server.java
@@ -3,15 +3,11 @@ package com.baeldung.cxf.introduction;
import javax.xml.ws.Endpoint;
public class Server {
- private Server() {
+ public static void main(String args[]) throws InterruptedException {
BaeldungImpl implementor = new BaeldungImpl();
String address = "http://localhost:8080/baeldung";
Endpoint.publish(address, implementor);
- }
-
- public static void main(String args[]) throws InterruptedException {
- new Server();
- System.out.println("Server ready");
+ System.out.println("Server ready...");
Thread.sleep(60 * 1000);
System.out.println("Server exiting");
System.exit(0);
diff --git a/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java b/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java
index 68bc4aa5e8..e1e5b60ec3 100644
--- a/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java
+++ b/apache-cxf/cxf-introduction/src/test/java/com/baeldung/cxf/introduction/StudentTest.java
@@ -21,7 +21,7 @@ public class StudentTest {
private Service service;
private Baeldung baeldungProxy;
- private Baeldung baeldungImpl;
+ private BaeldungImpl baeldungImpl;
{
service = Service.create(SERVICE_NAME);
diff --git a/apache-cxf/cxf-spring/pom.xml b/apache-cxf/cxf-spring/pom.xml
new file mode 100644
index 0000000000..431c35c51d
--- /dev/null
+++ b/apache-cxf/cxf-spring/pom.xml
@@ -0,0 +1,117 @@
+
+ 4.0.0
+ cxf-spring
+ war
+
+ com.baeldung
+ apache-cxf
+ 0.0.1-SNAPSHOT
+
+
+ 3.1.6
+ 4.3.1.RELEASE
+ 2.19.1
+
+
+
+
+ maven-war-plugin
+ 2.6
+
+ src/main/webapp/WEB-INF/web.xml
+
+
+
+ maven-surefire-plugin
+ ${surefire.version}
+
+
+ StudentTest.java
+
+
+
+
+
+
+
+ integration
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+ 1.5.0
+
+
+ jetty9x
+ embedded
+
+
+
+ localhost
+ 8080
+
+
+
+
+
+ start-server
+ pre-integration-test
+
+ start
+
+
+
+ stop-server
+ post-integration-test
+
+ stop
+
+
+
+
+
+ maven-surefire-plugin
+ ${surefire.version}
+
+
+ integration-test
+
+ test
+
+
+
+ none
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+ ${cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-transports-http-jetty
+ ${cxf.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+ org.springframework
+ spring-web
+ ${spring.version}
+
+
+
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java b/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java
new file mode 100644
index 0000000000..4f880e6ada
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Baeldung.java
@@ -0,0 +1,9 @@
+package com.baeldung.cxf.spring;
+
+import javax.jws.WebService;
+
+@WebService
+public interface Baeldung {
+ String hello(String name);
+ String register(Student student);
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java b/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java
new file mode 100644
index 0000000000..911ce7f876
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/BaeldungImpl.java
@@ -0,0 +1,17 @@
+package com.baeldung.cxf.spring;
+
+import javax.jws.WebService;
+
+@WebService(endpointInterface = "com.baeldung.cxf.spring.Baeldung")
+public class BaeldungImpl implements Baeldung {
+ private int counter;
+
+ public String hello(String name) {
+ return "Hello " + name + "!";
+ }
+
+ public String register(Student student) {
+ counter++;
+ return student.getName() + " is registered student number " + counter;
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java b/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java
new file mode 100644
index 0000000000..eb58057eb6
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/main/java/com/baeldung/cxf/spring/Student.java
@@ -0,0 +1,20 @@
+package com.baeldung.cxf.spring;
+
+public class Student {
+ private String name;
+
+ Student() {
+ }
+
+ public Student(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-spring/src/main/resources/client-beans.xml b/apache-cxf/cxf-spring/src/main/resources/client-beans.xml
new file mode 100644
index 0000000000..626252b565
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/main/resources/client-beans.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/apache-cxf/cxf-spring/src/main/webapp/WEB-INF/cxf-servlet.xml b/apache-cxf/cxf-spring/src/main/webapp/WEB-INF/cxf-servlet.xml
new file mode 100644
index 0000000000..9fe87ba9ee
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/apache-cxf/cxf-spring/src/main/webapp/WEB-INF/web.xml b/apache-cxf/cxf-spring/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..43a03b1d8b
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,14 @@
+
+
+
+ cxf
+ org.apache.cxf.transport.servlet.CXFServlet
+ 1
+
+
+ cxf
+ /services/*
+
+
diff --git a/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentTest.java b/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentTest.java
new file mode 100644
index 0000000000..44a9d11687
--- /dev/null
+++ b/apache-cxf/cxf-spring/src/test/java/com/baeldung/cxf/spring/StudentTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.cxf.spring;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class StudentTest {
+ private ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "client-beans.xml" });
+ private Baeldung baeldungProxy;
+
+ {
+ baeldungProxy = (Baeldung) context.getBean("client");
+ }
+
+ @Test
+ public void whenUsingHelloMethod_thenCorrect() {
+ String response = baeldungProxy.hello("John Doe");
+ assertEquals("Hello John Doe!", response);
+ }
+
+ @Test
+ public void whenUsingRegisterMethod_thenCorrect() {
+ Student student1 = new Student("Adam");
+ Student student2 = new Student("Eve");
+ String student1Response = baeldungProxy.register(student1);
+ String student2Response = baeldungProxy.register(student2);
+
+ assertEquals("Adam is registered student number 1", student1Response);
+ assertEquals("Eve is registered student number 2", student2Response);
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/pom.xml b/apache-cxf/pom.xml
index 41ae75a1de..022fc59f9b 100644
--- a/apache-cxf/pom.xml
+++ b/apache-cxf/pom.xml
@@ -7,6 +7,7 @@
pom
cxf-introduction
+ cxf-spring
diff --git a/core-java-8/.project b/core-java-8/.project
deleted file mode 100644
index a23ff42ae0..0000000000
--- a/core-java-8/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- core-java8
-
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.m2e.core.maven2Nature
-
-
diff --git a/core-java-8/README.md b/core-java-8/README.md
index b03d24c34e..e6bac2a4c9 100644
--- a/core-java-8/README.md
+++ b/core-java-8/README.md
@@ -3,9 +3,12 @@
## Core Java 8 Cookbooks and Examples
### Relevant Articles:
-// - [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda)
+- [Java 8 – Powerful Comparison with Lambdas](http://www.baeldung.com/java-8-sort-lambda)
- [Java – Directory Size](http://www.baeldung.com/java-folder-size)
- [Java – Try with Resources](http://www.baeldung.com/java-try-with-resources)
+- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial)
+- [Java 8 New Features](http://www.baeldung.com/java-8-new-features)
- [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)
-- [A Guide to the Java ExecutorService](http://www.baeldung.com/java-executor-service-tutorial)
+- [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
diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml
index 8c9bb36f7d..63df0e1b95 100644
--- a/core-java-8/pom.xml
+++ b/core-java-8/pom.xml
@@ -66,7 +66,8 @@
org.assertj
assertj-core
- 3.4.1
+ 3.5.1
+ test
diff --git a/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsTest.java b/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsTest.java
new file mode 100644
index 0000000000..d94f72b685
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/collectors/Java8CollectorsTest.java
@@ -0,0 +1,265 @@
+package com.baeldung.collectors;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.DoubleSummaryStatistics;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.stream.Collectors.averagingDouble;
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.counting;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.maxBy;
+import static java.util.stream.Collectors.partitioningBy;
+import static java.util.stream.Collectors.summarizingDouble;
+import static java.util.stream.Collectors.summingDouble;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class Java8CollectorsTest {
+
+ private final List givenList = Arrays.asList("a", "bb", "ccc", "dd");
+
+ @Test
+ public void whenCollectingToList_shouldCollectToList() throws Exception {
+ final List result = givenList.stream()
+ .collect(toList());
+
+ assertThat(result)
+ .containsAll(givenList);
+ }
+
+ @Test
+ public void whenCollectingToList_shouldCollectToSet() throws Exception {
+ final Set result = givenList.stream()
+ .collect(toSet());
+
+ assertThat(result)
+ .containsAll(givenList);
+ }
+
+ @Test
+ public void whenCollectingToCollection_shouldCollectToCollection() throws Exception {
+ final List result = givenList.stream()
+ .collect(toCollection(LinkedList::new));
+
+ assertThat(result)
+ .containsAll(givenList)
+ .isInstanceOf(LinkedList.class);
+ }
+
+ @Test
+ public void whenCollectingToImmutableCollection_shouldThrowException() throws Exception {
+ assertThatThrownBy(() -> {
+ givenList.stream()
+ .collect(toCollection(ImmutableList::of));
+ }).isInstanceOf(UnsupportedOperationException.class);
+
+ }
+
+ @Test
+ public void whenCollectingToMap_shouldCollectToMap() throws Exception {
+ final Map result = givenList.stream()
+ .collect(toMap(Function.identity(), String::length));
+
+ assertThat(result)
+ .containsEntry("a", 1)
+ .containsEntry("bb", 2)
+ .containsEntry("ccc", 3)
+ .containsEntry("dd", 2);
+ }
+
+ @Test
+ public void whenCollectingToMap_shouldCollectToMapMerging() throws Exception {
+ final Map result = givenList.stream()
+ .collect(toMap(Function.identity(), String::length, (i1, i2) -> i1));
+
+ assertThat(result)
+ .containsEntry("a", 1)
+ .containsEntry("bb", 2)
+ .containsEntry("ccc", 3)
+ .containsEntry("dd", 2);
+ }
+
+ @Test
+ public void whenCollectingAndThen_shouldCollect() throws Exception {
+ final List result = givenList.stream()
+ .collect(collectingAndThen(toList(), ImmutableList::copyOf));
+
+ assertThat(result)
+ .containsAll(givenList)
+ .isInstanceOf(ImmutableList.class);
+ }
+
+ @Test
+ public void whenJoining_shouldJoin() throws Exception {
+ final String result = givenList.stream()
+ .collect(joining());
+
+ assertThat(result)
+ .isEqualTo("abbcccdd");
+ }
+
+ @Test
+ public void whenJoiningWithSeparator_shouldJoinWithSeparator() throws Exception {
+ final String result = givenList.stream()
+ .collect(joining(" "));
+
+ assertThat(result)
+ .isEqualTo("a bb ccc dd");
+ }
+
+ @Test
+ public void whenJoiningWithSeparatorAndPrefixAndPostfix_shouldJoinWithSeparatorPrePost() throws Exception {
+ final String result = givenList.stream()
+ .collect(joining(" ", "PRE-", "-POST"));
+
+ assertThat(result)
+ .isEqualTo("PRE-a bb ccc dd-POST");
+ }
+
+ @Test
+ public void whenPartitioningBy_shouldPartition() throws Exception {
+ final Map> result = givenList.stream()
+ .collect(partitioningBy(s -> s.length() > 2));
+
+ assertThat(result)
+ .containsKeys(true, false)
+ .satisfies(booleanListMap -> {
+ assertThat(booleanListMap.get(true))
+ .contains("ccc");
+
+ assertThat(booleanListMap.get(false))
+ .contains("a", "bb", "dd");
+ });
+ }
+
+ @Test
+ public void whenCounting_shouldCount() throws Exception {
+ final Long result = givenList.stream()
+ .collect(counting());
+
+ assertThat(result)
+ .isEqualTo(4);
+ }
+
+ @Test
+ public void whenSummarizing_shouldSummarize() throws Exception {
+ final DoubleSummaryStatistics result = givenList.stream()
+ .collect(summarizingDouble(String::length));
+
+ assertThat(result.getAverage())
+ .isEqualTo(2);
+ assertThat(result.getCount())
+ .isEqualTo(4);
+ assertThat(result.getMax())
+ .isEqualTo(3);
+ assertThat(result.getMin())
+ .isEqualTo(1);
+ assertThat(result.getSum())
+ .isEqualTo(8);
+ }
+
+ @Test
+ public void whenAveraging_shouldAverage() throws Exception {
+ final Double result = givenList.stream()
+ .collect(averagingDouble(String::length));
+
+ assertThat(result)
+ .isEqualTo(2);
+ }
+
+ @Test
+ public void whenSumming_shouldSum() throws Exception {
+ final Double result = givenList.stream()
+ .collect(summingDouble(String::length));
+
+ assertThat(result)
+ .isEqualTo(8);
+ }
+
+ @Test
+ public void whenMaxingBy_shouldMaxBy() throws Exception {
+ final Optional result = givenList.stream()
+ .collect(maxBy(Comparator.naturalOrder()));
+
+ assertThat(result)
+ .isPresent()
+ .hasValue("dd");
+ }
+
+ @Test
+ public void whenGroupingBy_shouldGroupBy() throws Exception {
+ final Map> result = givenList.stream()
+ .collect(groupingBy(String::length, toSet()));
+
+ assertThat(result)
+ .containsEntry(1, newHashSet("a"))
+ .containsEntry(2, newHashSet("bb", "dd"))
+ .containsEntry(3, newHashSet("ccc"));
+ }
+
+
+ @Test
+ public void whenCreatingCustomCollector_shouldCollect() throws Exception {
+ final ImmutableSet result = givenList.stream()
+ .collect(toImmutableSet());
+
+ assertThat(result)
+ .isInstanceOf(ImmutableSet.class)
+ .contains("a", "bb", "ccc", "dd");
+
+ }
+
+ private static ImmutableSetCollector toImmutableSet() {
+ return new ImmutableSetCollector<>();
+ }
+
+ private static class ImmutableSetCollector implements Collector, ImmutableSet> {
+
+ @Override
+ public Supplier> supplier() {
+ return ImmutableSet::builder;
+ }
+
+ @Override
+ public BiConsumer, T> accumulator() {
+ return ImmutableSet.Builder::add;
+ }
+
+ @Override
+ public BinaryOperator> combiner() {
+ return (left, right) -> left.addAll(right.build());
+ }
+
+ @Override
+ public Function, ImmutableSet> finisher() {
+ return ImmutableSet.Builder::build;
+ }
+
+ @Override
+ public Set characteristics() {
+ return Sets.immutableEnumSet(Characteristics.UNORDERED);
+ }
+ }
+}
diff --git a/core-java/.settings/.jsdtscope b/core-java/.settings/.jsdtscope
deleted file mode 100644
index 7b3f0c8b9f..0000000000
--- a/core-java/.settings/.jsdtscope
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/core-java/.settings/org.eclipse.jdt.core.prefs b/core-java/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 1882edb712..0000000000
--- a/core-java/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,100 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.8
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=error
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=error
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.8
diff --git a/core-java/.settings/org.eclipse.jdt.ui.prefs b/core-java/.settings/org.eclipse.jdt.ui.prefs
deleted file mode 100644
index 471e9b0d81..0000000000
--- a/core-java/.settings/org.eclipse.jdt.ui.prefs
+++ /dev/null
@@ -1,55 +0,0 @@
-#Sat Jan 21 23:04:06 EET 2012
-eclipse.preferences.version=1
-editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
-sp_cleanup.add_default_serial_version_id=true
-sp_cleanup.add_generated_serial_version_id=false
-sp_cleanup.add_missing_annotations=true
-sp_cleanup.add_missing_deprecated_annotations=true
-sp_cleanup.add_missing_methods=false
-sp_cleanup.add_missing_nls_tags=false
-sp_cleanup.add_missing_override_annotations=true
-sp_cleanup.add_missing_override_annotations_interface_methods=true
-sp_cleanup.add_serial_version_id=false
-sp_cleanup.always_use_blocks=true
-sp_cleanup.always_use_parentheses_in_expressions=true
-sp_cleanup.always_use_this_for_non_static_field_access=false
-sp_cleanup.always_use_this_for_non_static_method_access=false
-sp_cleanup.convert_to_enhanced_for_loop=true
-sp_cleanup.correct_indentation=true
-sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=true
-sp_cleanup.make_local_variable_final=true
-sp_cleanup.make_parameters_final=true
-sp_cleanup.make_private_fields_final=false
-sp_cleanup.make_type_abstract_if_missing_method=false
-sp_cleanup.make_variable_declarations_final=true
-sp_cleanup.never_use_blocks=false
-sp_cleanup.never_use_parentheses_in_expressions=false
-sp_cleanup.on_save_use_additional_actions=true
-sp_cleanup.organize_imports=true
-sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
-sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
-sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
-sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
-sp_cleanup.remove_private_constructors=true
-sp_cleanup.remove_trailing_whitespaces=true
-sp_cleanup.remove_trailing_whitespaces_all=true
-sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
-sp_cleanup.remove_unnecessary_casts=true
-sp_cleanup.remove_unnecessary_nls_tags=false
-sp_cleanup.remove_unused_imports=true
-sp_cleanup.remove_unused_local_variables=false
-sp_cleanup.remove_unused_private_fields=true
-sp_cleanup.remove_unused_private_members=false
-sp_cleanup.remove_unused_private_methods=true
-sp_cleanup.remove_unused_private_types=true
-sp_cleanup.sort_members=false
-sp_cleanup.sort_members_all=false
-sp_cleanup.use_blocks=false
-sp_cleanup.use_blocks_only_for_return_and_throw=false
-sp_cleanup.use_parentheses_in_expressions=false
-sp_cleanup.use_this_for_non_static_field_access=true
-sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
-sp_cleanup.use_this_for_non_static_method_access=true
-sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/core-java/.settings/org.eclipse.m2e.core.prefs b/core-java/.settings/org.eclipse.m2e.core.prefs
deleted file mode 100644
index f897a7f1cb..0000000000
--- a/core-java/.settings/org.eclipse.m2e.core.prefs
+++ /dev/null
@@ -1,4 +0,0 @@
-activeProfiles=
-eclipse.preferences.version=1
-resolveWorkspaceProjects=true
-version=1
diff --git a/core-java/.settings/org.eclipse.m2e.wtp.prefs b/core-java/.settings/org.eclipse.m2e.wtp.prefs
deleted file mode 100644
index ef86089622..0000000000
--- a/core-java/.settings/org.eclipse.m2e.wtp.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false
diff --git a/core-java/.settings/org.eclipse.wst.common.component b/core-java/.settings/org.eclipse.wst.common.component
deleted file mode 100644
index e98377cb0f..0000000000
--- a/core-java/.settings/org.eclipse.wst.common.component
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/core-java/.settings/org.eclipse.wst.common.project.facet.core.xml b/core-java/.settings/org.eclipse.wst.common.project.facet.core.xml
deleted file mode 100644
index f4ef8aa0a5..0000000000
--- a/core-java/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/core-java/.settings/org.eclipse.wst.jsdt.ui.superType.container b/core-java/.settings/org.eclipse.wst.jsdt.ui.superType.container
deleted file mode 100644
index 3bd5d0a480..0000000000
--- a/core-java/.settings/org.eclipse.wst.jsdt.ui.superType.container
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/core-java/.settings/org.eclipse.wst.jsdt.ui.superType.name b/core-java/.settings/org.eclipse.wst.jsdt.ui.superType.name
deleted file mode 100644
index 05bd71b6ec..0000000000
--- a/core-java/.settings/org.eclipse.wst.jsdt.ui.superType.name
+++ /dev/null
@@ -1 +0,0 @@
-Window
\ No newline at end of file
diff --git a/core-java/.settings/org.eclipse.wst.validation.prefs b/core-java/.settings/org.eclipse.wst.validation.prefs
deleted file mode 100644
index cacf5451ae..0000000000
--- a/core-java/.settings/org.eclipse.wst.validation.prefs
+++ /dev/null
@@ -1,14 +0,0 @@
-DELEGATES_PREFERENCE=delegateValidatorList
-USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;
-USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.303.v201202090300
-eclipse.preferences.version=1
-override=true
-suspend=false
-vals/org.eclipse.jst.jsf.ui.JSFAppConfigValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPBatchValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.JSPContentValidator/global=FF01
-vals/org.eclipse.jst.jsp.core.TLDValidator/global=FF01
-vals/org.eclipse.wst.dtd.core.dtdDTDValidator/global=FF01
-vals/org.eclipse.wst.jsdt.web.core.JsBatchValidator/global=TF02
-vf.version=3
diff --git a/core-java/.settings/org.eclipse.wst.ws.service.policy.prefs b/core-java/.settings/org.eclipse.wst.ws.service.policy.prefs
deleted file mode 100644
index 9cfcabe16f..0000000000
--- a/core-java/.settings/org.eclipse.wst.ws.service.policy.prefs
+++ /dev/null
@@ -1,2 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.wst.ws.service.policy.projectEnabled=false
diff --git a/core-java/pom.xml b/core-java/pom.xml
index cb194a6d9f..bc533607e7 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -101,6 +101,22 @@
test
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+ org.testng
+ testng
+ ${testng.version}
+ test
+
+
+
+
org.mockito
mockito-core
@@ -169,6 +185,8 @@
1.3
4.12
1.10.19
+ 6.8
+ 3.5.1
4.4.1
4.5
diff --git a/core-java/src/test/java/org/baeldung/java/lists/ListAssertJTest.java b/core-java/src/test/java/org/baeldung/java/lists/ListAssertJTest.java
new file mode 100644
index 0000000000..b8926946a9
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/lists/ListAssertJTest.java
@@ -0,0 +1,25 @@
+package org.baeldung.java.lists;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ListAssertJTest {
+
+ private final List list1 = Arrays.asList("1", "2", "3", "4");
+ private final List list2 = Arrays.asList("1", "2", "3", "4");
+ private final List list3 = Arrays.asList("1", "2", "4", "3");
+
+ @Test
+ public void whenTestingForEquality_ShouldBeEqual() throws Exception {
+ assertThat(list1)
+ .isEqualTo(list2)
+ .isNotEqualTo(list3);
+
+ assertThat(list1.equals(list2)).isTrue();
+ assertThat(list1.equals(list3)).isFalse();
+ }
+}
diff --git a/core-java/src/test/java/org/baeldung/java/lists/ListJUnitTest.java b/core-java/src/test/java/org/baeldung/java/lists/ListJUnitTest.java
new file mode 100644
index 0000000000..7dddf6c2ce
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/lists/ListJUnitTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.java.lists;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ListJUnitTest {
+
+ private final List list1 = Arrays.asList("1", "2", "3", "4");
+ private final List list2 = Arrays.asList("1", "2", "3", "4");
+ private final List list3 = Arrays.asList("1", "2", "4", "3");
+
+ @Test
+ public void whenTestingForEquality_ShouldBeEqual() throws Exception {
+ Assert.assertEquals(list1, list2);
+ Assert.assertNotSame(list1, list2);
+ Assert.assertNotEquals(list1, list3);
+ }
+}
diff --git a/core-java/src/test/java/org/baeldung/java/lists/ListTestNGTest.java b/core-java/src/test/java/org/baeldung/java/lists/ListTestNGTest.java
new file mode 100644
index 0000000000..fa80d0e224
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/lists/ListTestNGTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.java.lists;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ListTestNGTest {
+
+ private final List list1 = Arrays.asList("1", "2", "3", "4");
+ private final List list2 = Arrays.asList("1", "2", "3", "4");
+ private final List list3 = Arrays.asList("1", "2", "4", "3");
+
+ @Test
+ public void whenTestingForEquality_ShouldBeEqual() throws Exception {
+ Assert.assertEquals(list1, list2);
+ Assert.assertNotSame(list1, list2);
+ Assert.assertNotEquals(list1, list3);
+ }
+}
diff --git a/spring-batch/.classpath b/couchbase-sdk-intro/.classpath
similarity index 98%
rename from spring-batch/.classpath
rename to couchbase-sdk-intro/.classpath
index e7ac9faf11..698778fef3 100644
--- a/spring-batch/.classpath
+++ b/couchbase-sdk-intro/.classpath
@@ -6,18 +6,18 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.jar b/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000000..5fd4d5023f
Binary files /dev/null and b/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.properties b/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..eb91947648
--- /dev/null
+++ b/couchbase-sdk-intro/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1 @@
+distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
\ No newline at end of file
diff --git a/spring-batch/.project b/couchbase-sdk-intro/.project
similarity index 69%
rename from spring-batch/.project
rename to couchbase-sdk-intro/.project
index 0159a7237c..b5b2a86ff9 100644
--- a/spring-batch/.project
+++ b/couchbase-sdk-intro/.project
@@ -1,6 +1,6 @@
- spring-batch
+ couchbase-intro
@@ -15,14 +15,8 @@
-
- org.springframework.ide.eclipse.core.springbuilder
-
-
-
- org.springframework.ide.eclipse.core.springnature
org.eclipse.jdt.core.javanature
org.eclipse.m2e.core.maven2Nature
diff --git a/couchbase-sdk-intro/mvnw b/couchbase-sdk-intro/mvnw
new file mode 100755
index 0000000000..a1ba1bf554
--- /dev/null
+++ b/couchbase-sdk-intro/mvnw
@@ -0,0 +1,233 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ #
+ # Look for the Apple JDKs first to preserve the existing behaviour, and then look
+ # for the new JDKs provided by Oracle.
+ #
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
+ #
+ # Oracle JDKs
+ #
+ export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=`/usr/libexec/java_home`
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Migwn, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+ # TODO classpath?
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ local basedir=$(pwd)
+ local wdir=$(pwd)
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ wdir=$(cd "$wdir/.."; pwd)
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} "$@"
diff --git a/couchbase-sdk-intro/mvnw.cmd b/couchbase-sdk-intro/mvnw.cmd
new file mode 100644
index 0000000000..2b934e89dd
--- /dev/null
+++ b/couchbase-sdk-intro/mvnw.cmd
@@ -0,0 +1,145 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+set MAVEN_CMD_LINE_ARGS=%*
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+
+set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
\ No newline at end of file
diff --git a/couchbase-sdk-intro/pom.xml b/couchbase-sdk-intro/pom.xml
new file mode 100644
index 0000000000..1c2ca5ee05
--- /dev/null
+++ b/couchbase-sdk-intro/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+ com.baeldung
+ couchbase-sdk-intro
+ 0.1-SNAPSHOT
+ jar
+ couchbase-sdk-intro
+ Intro to the Couchbase SDK
+
+
+
+
+ com.couchbase.client
+ java-client
+ ${couchbase.client.version}
+
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.7
+ 1.7
+
+
+
+
+
+
+ 1.7
+ UTF-8
+ 2.2.6
+
+
+
diff --git a/couchbase-sdk-intro/src/main/java/com/baeldung/couchbase/examples/CodeSnippets.java b/couchbase-sdk-intro/src/main/java/com/baeldung/couchbase/examples/CodeSnippets.java
new file mode 100644
index 0000000000..088f7af7b1
--- /dev/null
+++ b/couchbase-sdk-intro/src/main/java/com/baeldung/couchbase/examples/CodeSnippets.java
@@ -0,0 +1,96 @@
+package com.baeldung.couchbase.examples;
+
+import java.util.List;
+import java.util.UUID;
+
+import com.couchbase.client.core.CouchbaseException;
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.ReplicaMode;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.document.json.JsonObject;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+
+public class CodeSnippets {
+
+ static Cluster loadClusterWithDefaultEnvironment() {
+ return CouchbaseCluster.create("localhost");
+ }
+
+ static Cluster loadClusterWithCustomEnvironment() {
+ CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
+ .connectTimeout(10000)
+ .kvTimeout(3000)
+ .build();
+ return CouchbaseCluster.create(env, "localhost");
+ }
+
+ static Bucket loadDefaultBucketWithBlankPassword(Cluster cluster) {
+ return cluster.openBucket();
+ }
+
+ static Bucket loadBaeldungBucket(Cluster cluster) {
+ return cluster.openBucket("baeldung", "");
+ }
+
+ static JsonDocument insertExample(Bucket bucket) {
+ JsonObject content = JsonObject.empty()
+ .put("name", "John Doe")
+ .put("type", "Person")
+ .put("email", "john.doe@mydomain.com")
+ .put("homeTown", "Chicago")
+ ;
+ String id = UUID.randomUUID().toString();
+ JsonDocument document = JsonDocument.create(id, content);
+ JsonDocument inserted = bucket.insert(document);
+ return inserted;
+ }
+
+ static JsonDocument retrieveAndUpsertExample(Bucket bucket, String id) {
+ JsonDocument document = bucket.get(id);
+ JsonObject content = document.content();
+ content.put("homeTown", "Kansas City");
+ JsonDocument upserted = bucket.upsert(document);
+ return upserted;
+ }
+
+ static JsonDocument replaceExample(Bucket bucket, String id) {
+ JsonDocument document = bucket.get(id);
+ JsonObject content = document.content();
+ content.put("homeTown", "Milwaukee");
+ JsonDocument replaced = bucket.replace(document);
+ return replaced;
+ }
+
+ static JsonDocument removeExample(Bucket bucket, String id) {
+ JsonDocument removed = bucket.remove(id);
+ return removed;
+ }
+
+ static JsonDocument getFirstFromReplicaExample(Bucket bucket, String id) {
+ try{
+ return bucket.get(id);
+ }
+ catch(CouchbaseException e) {
+ List list = bucket.getFromReplica(id, ReplicaMode.FIRST);
+ if(!list.isEmpty()) {
+ return list.get(0);
+ }
+ }
+ return null;
+ }
+
+ static JsonDocument getLatestReplicaVersion(Bucket bucket, String id) {
+ long maxCasValue = -1;
+ JsonDocument latest = null;
+ for(JsonDocument replica : bucket.getFromReplica(id, ReplicaMode.ALL)) {
+ if(replica.cas() > maxCasValue) {
+ latest = replica;
+ maxCasValue = replica.cas();
+ }
+ }
+ return latest;
+ }
+}
diff --git a/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.jar b/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000000..5fd4d5023f
Binary files /dev/null and b/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.properties b/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..eb91947648
--- /dev/null
+++ b/couchbase-sdk-spring-service/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1 @@
+distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
\ No newline at end of file
diff --git a/core-java/.springBeans b/couchbase-sdk-spring-service/.springBeans
similarity index 71%
rename from core-java/.springBeans
rename to couchbase-sdk-spring-service/.springBeans
index a79097f40d..ff32b84d3b 100644
--- a/core-java/.springBeans
+++ b/couchbase-sdk-spring-service/.springBeans
@@ -1,14 +1,15 @@
1
-
+
- src/main/webapp/WEB-INF/api-servlet.xml
+
+
diff --git a/couchbase-sdk-spring-service/mvnw b/couchbase-sdk-spring-service/mvnw
new file mode 100755
index 0000000000..a1ba1bf554
--- /dev/null
+++ b/couchbase-sdk-spring-service/mvnw
@@ -0,0 +1,233 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ #
+ # Look for the Apple JDKs first to preserve the existing behaviour, and then look
+ # for the new JDKs provided by Oracle.
+ #
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
+ #
+ # Oracle JDKs
+ #
+ export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=`/usr/libexec/java_home`
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Migwn, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+ # TODO classpath?
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ local basedir=$(pwd)
+ local wdir=$(pwd)
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ wdir=$(cd "$wdir/.."; pwd)
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} "$@"
diff --git a/couchbase-sdk-spring-service/mvnw.cmd b/couchbase-sdk-spring-service/mvnw.cmd
new file mode 100644
index 0000000000..2b934e89dd
--- /dev/null
+++ b/couchbase-sdk-spring-service/mvnw.cmd
@@ -0,0 +1,145 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+set MAVEN_CMD_LINE_ARGS=%*
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+
+set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
\ No newline at end of file
diff --git a/couchbase-sdk-spring-service/pom.xml b/couchbase-sdk-spring-service/pom.xml
new file mode 100644
index 0000000000..d344f8c756
--- /dev/null
+++ b/couchbase-sdk-spring-service/pom.xml
@@ -0,0 +1,102 @@
+
+
+ 4.0.0
+ com.baeldung
+ couchbase-sdk-spring-service
+ 0.1-SNAPSHOT
+ jar
+ couchbase-sdk-spring-service
+ Intro to the Couchbase SDK
+
+
+
+
+ com.couchbase.client
+ java-client
+ ${couchbase.client.version}
+
+
+
+
+ org.springframework
+ spring-context
+ ${spring-framework.version}
+
+
+ org.springframework
+ spring-context-support
+ ${spring-framework.version}
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+ compile
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${org.slf4j.version}
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${org.slf4j.version}
+
+
+
+
+ org.springframework
+ spring-test
+ ${spring-framework.version}
+ test
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.7
+ 1.7
+
+
+
+
+
+
+ 1.7
+ UTF-8
+ 2.2.6
+ 4.2.4.RELEASE
+ 1.1.3
+ 1.7.12
+ 4.11
+ 3.4
+
+
+
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/FluentPersonDocumentConverter.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/FluentPersonDocumentConverter.java
new file mode 100644
index 0000000000..8210c10b3a
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/FluentPersonDocumentConverter.java
@@ -0,0 +1,31 @@
+package com.baeldung.couchbase.person;
+
+import org.springframework.stereotype.Service;
+
+import com.baeldung.couchbase.service.JsonDocumentConverter;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.document.json.JsonObject;
+
+@Service
+public class FluentPersonDocumentConverter implements JsonDocumentConverter {
+
+ @Override
+ public JsonDocument toDocument(Person p) {
+ JsonObject content = JsonObject.empty()
+ .put("type", "Person")
+ .put("name", p.getName())
+ .put("homeTown", p.getHomeTown());
+ return JsonDocument.create(p.getId(), content);
+ }
+
+ @Override
+ public Person fromDocument(JsonDocument doc) {
+ JsonObject content = doc.content();
+ return Person.Builder.newInstance()
+ .id(doc.id())
+ .type("Person")
+ .name(content.getString("name"))
+ .homeTown(content.getString("homeTown"))
+ .build();
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/Person.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/Person.java
new file mode 100644
index 0000000000..48b7a38780
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/Person.java
@@ -0,0 +1,85 @@
+package com.baeldung.couchbase.person;
+
+public class Person {
+
+ private String id;
+ private String type;
+ private String name;
+ private String homeTown;
+
+ Person() {}
+
+ public Person(Builder b) {
+ this.id = b.id;
+ this.type = b.type;
+ this.name = b.name;
+ this.homeTown = b.homeTown;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getHomeTown() {
+ return homeTown;
+ }
+
+ public void setHomeTown(String homeTown) {
+ this.homeTown = homeTown;
+ }
+
+ public static class Builder {
+ private String id;
+ private String type;
+ private String name;
+ private String homeTown;
+
+ public static Builder newInstance() {
+ return new Builder();
+ }
+
+ public Person build() {
+ return new Person(this);
+ }
+
+ public Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder type(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder homeTown(String homeTown) {
+ this.homeTown = homeTown;
+ return this;
+ }
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonCrudService.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonCrudService.java
new file mode 100644
index 0000000000..0203bf30bb
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonCrudService.java
@@ -0,0 +1,68 @@
+package com.baeldung.couchbase.person;
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.baeldung.couchbase.service.CrudService;
+import com.baeldung.couchbase.service.TutorialBucketService;import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.ReplicaMode;
+import com.couchbase.client.java.document.JsonDocument;
+
+@Service
+public class PersonCrudService implements CrudService {
+
+ @Autowired
+ private TutorialBucketService bucketService;
+
+ @Autowired
+ private PersonDocumentConverter converter;
+
+ private Bucket bucket;
+
+ @PostConstruct
+ private void init() {
+ bucket = bucketService.getBucket();
+ }
+
+ @Override
+ public void create(Person person) {
+ if(person.getId() == null) {
+ person.setId(UUID.randomUUID().toString());
+ }
+ JsonDocument document = converter.toDocument(person);
+ bucket.insert(document);
+ }
+
+ @Override
+ public Person read(String id) {
+ JsonDocument doc = bucket.get(id);
+ return (doc != null ? converter.fromDocument(doc) : null);
+ }
+
+ @Override
+ public Person readFromReplica(String id) {
+ List docs = bucket.getFromReplica(id, ReplicaMode.FIRST);
+ return (docs.isEmpty() ? null : converter.fromDocument(docs.get(0)));
+ }
+
+ @Override
+ public void update(Person person) {
+ JsonDocument document = converter.toDocument(person);
+ bucket.upsert(document);
+ }
+
+ @Override
+ public void delete(String id) {
+ bucket.remove(id);
+ }
+
+ @Override
+ public boolean exists(String id) {
+ return bucket.exists(id);
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonDocumentConverter.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonDocumentConverter.java
new file mode 100644
index 0000000000..cfb20a2bfb
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/PersonDocumentConverter.java
@@ -0,0 +1,31 @@
+package com.baeldung.couchbase.person;
+
+import org.springframework.stereotype.Service;
+
+import com.baeldung.couchbase.service.JsonDocumentConverter;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.document.json.JsonObject;
+
+@Service
+public class PersonDocumentConverter implements JsonDocumentConverter {
+
+ @Override
+ public JsonDocument toDocument(Person p) {
+ JsonObject content = JsonObject.empty()
+ .put("type", "Person")
+ .put("name", p.getName())
+ .put("homeTown", p.getHomeTown());
+ return JsonDocument.create(p.getId(), content);
+ }
+
+ @Override
+ public Person fromDocument(JsonDocument doc) {
+ JsonObject content = doc.content();
+ Person p = new Person();
+ p.setId(doc.id());
+ p.setType("Person");
+ p.setName(content.getString("name"));
+ p.setHomeTown(content.getString("homeTown"));
+ return p;
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/RegistrationService.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/RegistrationService.java
new file mode 100644
index 0000000000..53af1c4041
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/person/RegistrationService.java
@@ -0,0 +1,29 @@
+package com.baeldung.couchbase.person;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.couchbase.client.core.CouchbaseException;
+
+@Service
+public class RegistrationService {
+
+ @Autowired
+ private PersonCrudService crud;
+
+ public void registerNewPerson(String name, String homeTown) {
+ Person person = new Person();
+ person.setName(name);
+ person.setHomeTown(homeTown);
+ crud.create(person);
+ }
+
+ public Person findRegistrant(String id) {
+ try{
+ return crud.read(id);
+ }
+ catch(CouchbaseException e) {
+ return crud.readFromReplica(id);
+ }
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/BucketService.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/BucketService.java
new file mode 100644
index 0000000000..c2562dd38e
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/BucketService.java
@@ -0,0 +1,9 @@
+package com.baeldung.couchbase.service;
+
+import com.couchbase.client.java.Bucket;
+
+public interface BucketService {
+
+ Bucket getBucket();
+
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/ClusterService.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/ClusterService.java
new file mode 100644
index 0000000000..4713893899
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/ClusterService.java
@@ -0,0 +1,17 @@
+package com.baeldung.couchbase.service;
+
+import java.util.List;
+
+import com.couchbase.client.java.AsyncBucket;
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.document.JsonDocument;
+
+public interface ClusterService {
+
+ Bucket openBucket(String name, String password);
+
+ List getDocuments(Bucket bucket, Iterable keys);
+
+ List getDocumentsAsync(AsyncBucket bucket, Iterable keys);
+
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/ClusterServiceImpl.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/ClusterServiceImpl.java
new file mode 100644
index 0000000000..3c355d2a27
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/ClusterServiceImpl.java
@@ -0,0 +1,84 @@
+package com.baeldung.couchbase.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.PostConstruct;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import com.couchbase.client.java.AsyncBucket;
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.Cluster;
+import com.couchbase.client.java.CouchbaseCluster;
+import com.couchbase.client.java.document.JsonDocument;
+import com.couchbase.client.java.env.CouchbaseEnvironment;
+import com.couchbase.client.java.env.DefaultCouchbaseEnvironment;
+
+import rx.Observable;
+import rx.functions.Action1;
+import rx.functions.Func1;
+
+@Service
+public class ClusterServiceImpl implements ClusterService {
+ private static final Logger logger = LoggerFactory.getLogger(ClusterServiceImpl.class);
+
+ private Cluster cluster;
+ private Map buckets = new ConcurrentHashMap<>();
+
+ @PostConstruct
+ private void init() {
+ CouchbaseEnvironment env = DefaultCouchbaseEnvironment.create();
+ cluster = CouchbaseCluster.create(env, "localhost");
+ }
+
+ @Override
+ synchronized public Bucket openBucket(String name, String password) {
+ if(!buckets.containsKey(name)) {
+ Bucket bucket = cluster.openBucket(name, password);
+ buckets.put(name, bucket);
+ }
+ return buckets.get(name);
+ }
+
+ @Override
+ public List getDocuments(Bucket bucket, Iterable keys) {
+ List docs = new ArrayList<>();
+ for(String key : keys) {
+ JsonDocument doc = bucket.get(key);
+ if(doc != null) {
+ docs.add(doc);
+ }
+ }
+ return docs;
+ }
+
+ @Override
+ public List getDocumentsAsync(final AsyncBucket asyncBucket, Iterable keys) {
+ Observable asyncBulkGet = Observable
+ .from(keys)
+ .flatMap(new Func1>() {
+ public Observable call(String key) {
+ return asyncBucket.get(key);
+ }
+ });
+
+ final List docs = new ArrayList<>();
+ try {
+ asyncBulkGet.toBlocking()
+ .forEach(new Action1() {
+ public void call(JsonDocument doc) {
+ docs.add(doc);
+ }
+ });
+ } catch (Exception e) {
+ logger.error("Error during bulk get", e);
+ }
+
+ return docs;
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/CrudService.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/CrudService.java
new file mode 100644
index 0000000000..20ee851b39
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/CrudService.java
@@ -0,0 +1,16 @@
+package com.baeldung.couchbase.service;
+
+public interface CrudService {
+
+ void create(T t);
+
+ T read(String id);
+
+ T readFromReplica(String id);
+
+ void update(T t);
+
+ void delete(String id);
+
+ boolean exists(String id);
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/JsonDocumentConverter.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/JsonDocumentConverter.java
new file mode 100644
index 0000000000..87331d2a17
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/JsonDocumentConverter.java
@@ -0,0 +1,10 @@
+package com.baeldung.couchbase.service;
+
+import com.couchbase.client.java.document.JsonDocument;
+
+public interface JsonDocumentConverter {
+
+ JsonDocument toDocument(T t);
+
+ T fromDocument(JsonDocument doc);
+}
diff --git a/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/TutorialBucketService.java b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/TutorialBucketService.java
new file mode 100644
index 0000000000..903a568399
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/java/com/baeldung/couchbase/service/TutorialBucketService.java
@@ -0,0 +1,29 @@
+package com.baeldung.couchbase.service;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import com.couchbase.client.java.Bucket;
+
+@Service
+@Qualifier("TutorialBucketService")
+public class TutorialBucketService implements BucketService {
+
+ @Autowired
+ private ClusterService couchbase;
+
+ private Bucket bucket;
+
+ @PostConstruct
+ private void init() {
+ bucket = couchbase.openBucket("baeldung-tutorial", "");
+ }
+
+ @Override
+ public Bucket getBucket() {
+ return bucket;
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/main/resources/application.properties b/couchbase-sdk-spring-service/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/couchbase-sdk-spring-service/src/main/resources/logback.xml b/couchbase-sdk-spring-service/src/main/resources/logback.xml
new file mode 100644
index 0000000000..efcc6fb4c7
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/main/resources/logback.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ web - %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTest.java b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTest.java
new file mode 100644
index 0000000000..d1cc807f7a
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTest.java
@@ -0,0 +1,13 @@
+package com.baeldung.couchbase;
+
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { IntegrationTestConfig.class })
+@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
+public abstract class IntegrationTest {
+}
diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTestConfig.java b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTestConfig.java
new file mode 100644
index 0000000000..d593aac52d
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/IntegrationTestConfig.java
@@ -0,0 +1,9 @@
+package com.baeldung.couchbase;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(basePackages={"com.baeldung.couchbase"})
+public class IntegrationTestConfig {
+}
diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/person/PersonCrudServiceTest.java b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/person/PersonCrudServiceTest.java
new file mode 100644
index 0000000000..e19e90769c
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/person/PersonCrudServiceTest.java
@@ -0,0 +1,82 @@
+package com.baeldung.couchbase.person;
+
+import static org.junit.Assert.*;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.baeldung.couchbase.IntegrationTest;
+
+public class PersonCrudServiceTest extends IntegrationTest {
+
+ private static final String CLARK_KENT = "Clark Kent";
+ private static final String SMALLVILLE = "Smallville";
+ private static final String CLARK_KENT_ID = "Person:ClarkKent";
+
+ private Person clarkKent;
+
+ @Autowired
+ private PersonCrudService personService;
+
+ @PostConstruct
+ private void init() {
+ clarkKent = personService.read(CLARK_KENT_ID);
+ if(clarkKent == null) {
+ clarkKent = buildClarkKent();
+ personService.create(clarkKent);
+ }
+ }
+
+ @Test
+ public final void givenRandomPerson_whenCreate_thenPersonPersisted() {
+ Person person = randomPerson();
+ personService.create(person);
+ String id = person.getId();
+ assertNotNull(personService.read(id));
+ }
+
+ @Test
+ public final void givenClarkKentId_whenRead_thenReturnsClarkKent() {
+ Person person = personService.read(CLARK_KENT_ID);
+ assertNotNull(person);
+ }
+
+ @Test
+ public final void givenNewHometown_whenUpdate_thenNewHometownPersisted() {
+ Person expected = randomPerson();
+ personService.create(expected);
+ String updatedHomeTown = RandomStringUtils.randomAlphabetic(12);
+ expected.setHomeTown(updatedHomeTown);
+ personService.update(expected);
+ Person actual = personService.read(expected.getId());
+ assertNotNull(actual);
+ assertEquals(expected.getHomeTown(), actual.getHomeTown());
+ }
+
+ @Test
+ public final void givenRandomPerson_whenDelete_thenPersonNotInBucket() {
+ Person person = randomPerson();
+ personService.create(person);
+ String id = person.getId();
+ personService.delete(id);
+ assertNull(personService.read(id));
+ }
+
+ private Person buildClarkKent() {
+ return Person.Builder.newInstance()
+ .id(CLARK_KENT_ID)
+ .name(CLARK_KENT)
+ .homeTown(SMALLVILLE)
+ .build();
+ }
+
+ private Person randomPerson() {
+ return Person.Builder.newInstance()
+ .name(RandomStringUtils.randomAlphabetic(10))
+ .homeTown(RandomStringUtils.randomAlphabetic(10))
+ .build();
+ }
+}
diff --git a/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/service/ClusterServiceTest.java b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/service/ClusterServiceTest.java
new file mode 100644
index 0000000000..7795f41c93
--- /dev/null
+++ b/couchbase-sdk-spring-service/src/test/java/com/baeldung/couchbase/service/ClusterServiceTest.java
@@ -0,0 +1,34 @@
+package com.baeldung.couchbase.service;
+
+import static 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.TestExecutionListeners;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
+
+import com.baeldung.couchbase.IntegrationTest;
+import com.baeldung.couchbase.IntegrationTestConfig;
+import com.couchbase.client.java.Bucket;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { IntegrationTestConfig.class })
+@TestExecutionListeners(listeners = { DependencyInjectionTestExecutionListener.class })
+public class ClusterServiceTest extends IntegrationTest {
+
+ @Autowired
+ private ClusterService couchbaseService;
+
+ private Bucket defaultBucket;
+
+ @Test
+ public void whenOpenBucket_thenBucketIsNotNull() throws Exception {
+ defaultBucket = couchbaseService.openBucket("default", "");
+ assertNotNull(defaultBucket);
+ assertFalse(defaultBucket.isClosed());
+ defaultBucket.close();
+ }
+}
diff --git a/mutation-testing/README.md b/mutation-testing/README.md
new file mode 100644
index 0000000000..5dd60620ba
--- /dev/null
+++ b/mutation-testing/README.md
@@ -0,0 +1,6 @@
+=========
+
+## Mutation Testing
+
+### Relevant Articles:
+- [Introduction to Mutation Testing Using the PITest Library](http://www.baeldung.com/java-mutation-testing-with-pitest)
diff --git a/mutation-testing/pom.xml b/mutation-testing/pom.xml
new file mode 100644
index 0000000000..83012ab8fe
--- /dev/null
+++ b/mutation-testing/pom.xml
@@ -0,0 +1,38 @@
+
+ 4.0.0
+ com.baeldung
+ mutation-testing
+ 0.1-SNAPSHOT
+ mutation-testing
+
+
+ org.pitest
+ pitest-parent
+ 1.1.10
+ pom
+
+
+ junit
+ junit
+ 4.9
+
+
+
+
+
+ org.pitest
+ pitest-maven
+ 1.1.10
+
+
+ com.baeldung.testing.mutation.*
+
+
+ com.baeldung.mutation.test.*
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mutation-testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java b/mutation-testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java
new file mode 100644
index 0000000000..0b166f1557
--- /dev/null
+++ b/mutation-testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java
@@ -0,0 +1,15 @@
+package com.baeldung.testing.mutation;
+
+public class Palindrome {
+
+ public boolean isPalindrome(String inputString) {
+ if (inputString.length() == 0) {
+ return true;
+ } else {
+ char firstChar = inputString.charAt(0);
+ char lastChar = inputString.charAt(inputString.length() - 1);
+ String mid = inputString.substring(1, inputString.length() - 1);
+ return (firstChar == lastChar) && isPalindrome(mid);
+ }
+ }
+}
diff --git a/mutation-testing/src/test/java/com/baeldung/mutation/test/TestPalindrome.java b/mutation-testing/src/test/java/com/baeldung/mutation/test/TestPalindrome.java
new file mode 100644
index 0000000000..1410135883
--- /dev/null
+++ b/mutation-testing/src/test/java/com/baeldung/mutation/test/TestPalindrome.java
@@ -0,0 +1,29 @@
+package com.baeldung.mutation.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.baeldung.testing.mutation.Palindrome;
+
+public class TestPalindrome {
+
+ @Test
+ public void acceptsPalindrome() {
+ Palindrome palindromeTester = new Palindrome();
+ assertTrue(palindromeTester.isPalindrome("noon"));
+ }
+
+ @Test
+ public void rejectsNonPalindrome(){
+ Palindrome palindromeTester = new Palindrome();
+ assertFalse(palindromeTester.isPalindrome("box"));
+ }
+
+ @Test
+ public void rejectsNearPalindrome(){
+ Palindrome palindromeTester = new Palindrome();
+ assertFalse(palindromeTester.isPalindrome("neon"));
+ }
+}
diff --git a/pom.xml b/pom.xml
index fb6d4d0761..1966d1485a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,6 +42,7 @@
spring-apache-camel
spring-batch
spring-boot
+ spring-controller
spring-data-cassandra
spring-data-elasticsearch
spring-data-mongodb
@@ -77,9 +78,10 @@
spring-zuul
jsf
xml
-
lombok
redis
+
+ mutation-testing
diff --git a/core-java/.classpath b/rest-assured-tutorial/.classpath
similarity index 100%
rename from core-java/.classpath
rename to rest-assured-tutorial/.classpath
index ca829f1262..8ebf6d9c31 100644
--- a/core-java/.classpath
+++ b/rest-assured-tutorial/.classpath
@@ -1,5 +1,11 @@
+
+
+
+
+
+
@@ -21,12 +27,6 @@
-
-
-
-
-
-
diff --git a/core-java/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch b/rest-assured-tutorial/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
similarity index 100%
rename from core-java/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
rename to rest-assured-tutorial/.externalToolBuilders/org.eclipse.wst.jsdt.core.javascriptValidator.launch
diff --git a/rest-assured-tutorial/.gitignore b/rest-assured-tutorial/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/rest-assured-tutorial/.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/.project b/rest-assured-tutorial/.project
similarity index 96%
rename from core-java/.project
rename to rest-assured-tutorial/.project
index 12bfa7d869..8333cfc36c 100644
--- a/core-java/.project
+++ b/rest-assured-tutorial/.project
@@ -1,6 +1,6 @@
- core-java
+ rest-assured-tutorial
diff --git a/rest-assured-tutorial/README.md b/rest-assured-tutorial/README.md
new file mode 100644
index 0000000000..8b81626967
--- /dev/null
+++ b/rest-assured-tutorial/README.md
@@ -0,0 +1,7 @@
+=========
+
+## A Guide To REST-Assured
+
+
+### Relevant Articles:
+
diff --git a/rest-assured-tutorial/pom.xml b/rest-assured-tutorial/pom.xml
new file mode 100644
index 0000000000..12c1fe25ca
--- /dev/null
+++ b/rest-assured-tutorial/pom.xml
@@ -0,0 +1,86 @@
+
+ 4.0.0
+ com.baeldung
+ rest-assured
+ 0.1.0-SNAPSHOT
+
+ rest-assured
+
+
+
+
+
+ io.rest-assured
+ rest-assured
+ 3.0.0
+ test
+
+
+ io.rest-assured
+ json-schema-validator
+ 3.0.0
+
+
+ com.github.fge
+ json-schema-validator
+ 2.2.6
+
+
+ com.github.fge
+ json-schema-core
+ 1.2.5
+
+
+
+
+
+
+
+ junit
+ junit
+ 4.3
+ test
+
+
+
+ org.hamcrest
+ hamcrest-all
+ 1.3
+
+
+
+
+
+ rest-assured
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rest-assured-tutorial/src/test/java/com/baeldung/restassured/RestAssuredTest.java b/rest-assured-tutorial/src/test/java/com/baeldung/restassured/RestAssuredTest.java
new file mode 100644
index 0000000000..55c7a6f0d0
--- /dev/null
+++ b/rest-assured-tutorial/src/test/java/com/baeldung/restassured/RestAssuredTest.java
@@ -0,0 +1,151 @@
+package com.baeldung.restassured;
+
+import static io.restassured.RestAssured.get;
+import static io.restassured.RestAssured.post;
+import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
+import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.containsString;
+import io.restassured.module.jsv.JsonSchemaValidator;
+import static org.hamcrest.xml.HasXPath.hasXPath;
+
+import org.junit.Test;
+
+import com.github.fge.jsonschema.SchemaVersion;
+import com.github.fge.jsonschema.cfg.ValidationConfiguration;
+import com.github.fge.jsonschema.main.JsonSchemaFactory;
+
+public class RestAssuredTest {
+
+ @Test
+ public void givenJsonResponse_whenKeyValuePairMatches_thenCorrect() {
+ JsonSchemaFactory factory = JsonSchemaFactory
+ .newBuilder()
+ .setValidationConfiguration(
+ ValidationConfiguration.newBuilder()
+ .setDefaultVersion(SchemaVersion.DRAFTV3)
+ .freeze()).freeze();
+ JsonSchemaValidator.settings = settings().with()
+ .jsonSchemaFactory(factory).and().with()
+ .checkedValidation(false);
+ }
+
+ @Test
+ public void givenJsonArrayOfSimilarObjects_whenHasGivenValuesForGivenKey_thenCorrect() {
+
+ }
+
+ @Test
+ public void givenUrl_whenSuccessOnGetsResponse_andJsonHasRequiredKV_thenCorrect() {
+
+ get("/events?id=390").then().statusCode(200).assertThat()
+ .body("data.id", equalTo(390));
+
+ }
+
+ @Test
+ public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() {
+
+ get("/events?id=390").then().assertThat()
+ .body("odds.price", hasItems("1.30", "5.25"));
+
+ }
+
+ @Test
+ public void givenUrl_whenJsonResponseConformsToSchema_thenCorrect() {
+ get("/events?id=390").then().assertThat()
+ .body(matchesJsonSchemaInClasspath("event_0.json"));
+ }
+
+ @Test
+ public void givenUrl_whenValidatesResponseWithInstanceSettings_thenCorrect() {
+ JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory
+ .newBuilder()
+ .setValidationConfiguration(
+ ValidationConfiguration.newBuilder()
+ .setDefaultVersion(SchemaVersion.DRAFTV4)
+ .freeze()).freeze();
+
+ get("/events?id=390")
+ .then()
+ .assertThat()
+ .body(matchesJsonSchemaInClasspath("event_0.json").using(
+ jsonSchemaFactory));
+
+ }
+
+ @Test
+ public void givenUrl_whenValidatesResponseWithStaticSettings_thenCorrect() {
+
+ get("/events?id=390")
+ .then()
+ .assertThat()
+ .body(matchesJsonSchemaInClasspath("event_0.json").using(
+ settings().with().checkedValidation(false)));
+
+ }
+
+ @Test
+ public void givenUrl_whenCheckingFloatValuePasses_thenCorrect() {
+ get("/odd").then().assertThat().body("odd.ck", equalTo(12.2f));
+ }
+
+ @Test
+ public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() {
+ post("/employees").then().assertThat()
+ .body("employees.employee.first-name", equalTo("Jane"));
+ }
+
+ @Test
+ public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() {
+ post("/employees").then().assertThat()
+ .body("employees.employee.first-name", equalTo("Jane"))
+ .body("employees.employee.last-name", equalTo("Daisy"))
+ .body("employees.employee.sex", equalTo("f"));
+ }
+
+ @Test
+ public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() {
+ post("/employees")
+ .then()
+ .assertThat()
+ .body("employees.employee.first-name", equalTo("Jane"),
+ "employees.employee.last-name", equalTo("Daisy"),
+ "employees.employee.sex", equalTo("f"));
+ }
+
+ @Test
+ public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() {
+ post("/employees")
+ .then()
+ .assertThat()
+ .body(hasXPath("/employees/employee/first-name",
+ containsString("Ja")));
+
+ }
+
+ @Test
+ public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() {
+ post("/employees")
+ .then()
+ .assertThat()
+ .body(hasXPath("/employees/employee/first-name[text()='Jane']"));
+
+ }
+
+ @Test
+ public void givenUrl_whenVerifiesScienceTeacherFromXml_thenCorrect() {
+ get("/teachers")
+ .then()
+ .body("teachers.teacher.find { it.@department == 'science' }.subject",
+ hasItems("math", "physics"));
+ }
+
+ @Test
+ public void givenUrl_whenVerifiesOddPricesAccuratelyByStatus_thenCorrect() {
+ get("/odds").then().body("odds.findAll { it.status > 0 }.price",
+ hasItems(1.30f, 1.20f));
+ }
+
+}
diff --git a/rest-assured-tutorial/src/test/resources/.gitignore b/rest-assured-tutorial/src/test/resources/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/rest-assured-tutorial/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/rest-assured-tutorial/src/test/resources/employees.xml b/rest-assured-tutorial/src/test/resources/employees.xml
new file mode 100644
index 0000000000..64e382976d
--- /dev/null
+++ b/rest-assured-tutorial/src/test/resources/employees.xml
@@ -0,0 +1,22 @@
+
+
+ Jane
+ Daisy
+ f
+
+
+ John
+ Doe
+ m
+
+
+ Billy
+ Getty
+ m
+
+
+ Hill
+ Clinton
+ f
+
+
\ No newline at end of file
diff --git a/rest-assured-tutorial/src/test/resources/event0.json b/rest-assured-tutorial/src/test/resources/event0.json
new file mode 100644
index 0000000000..77e26c347e
--- /dev/null
+++ b/rest-assured-tutorial/src/test/resources/event0.json
@@ -0,0 +1,37 @@
+{
+ "id": "390",
+ "data": {
+ "countryId": 35,
+ "countryName": "Norway",
+ "leagueName": "Norway 3",
+ "status": 0,
+ "sportName": "Soccer",
+ "time": "2016-06-12T12:00:00Z"
+ },
+ "odds": [{
+ "price": 1.30,
+ "status": 0,
+ "ck": 12.2,
+ "name": "1"
+ },
+ {
+ "price": 5.25,
+ "status": 1,
+ "ck": 13.1,
+ "name": "X"
+ },
+ {
+ "price": 2.70,
+ "status": 0,
+ "ck": 12.2,
+ "name": "0"
+ },
+ {
+ "price": 1.20,
+ "status": 2,
+ "ck": 13.1,
+ "name": "2"
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/rest-assured-tutorial/src/test/resources/odds.json b/rest-assured-tutorial/src/test/resources/odds.json
new file mode 100644
index 0000000000..8b3dc166c5
--- /dev/null
+++ b/rest-assured-tutorial/src/test/resources/odds.json
@@ -0,0 +1,28 @@
+{
+ "odds": [{
+ "price": 1.30,
+ "status": 0,
+ "ck": 12.2,
+ "name": "1"
+ },
+ {
+ "price": 5.25,
+ "status": 1,
+ "ck": 13.1,
+ "name": "X"
+ },
+ {
+ "price": 2.70,
+ "status": 0,
+ "ck": 12.2,
+ "name": "0"
+ },
+ {
+ "price": 1.20,
+ "status": 2,
+ "ck": 13.1,
+ "name": "2"
+ }
+
+ ]
+}
\ No newline at end of file
diff --git a/rest-assured-tutorial/src/test/resources/teachers.xml b/rest-assured-tutorial/src/test/resources/teachers.xml
new file mode 100644
index 0000000000..9c073d5a38
--- /dev/null
+++ b/rest-assured-tutorial/src/test/resources/teachers.xml
@@ -0,0 +1,10 @@
+
+
+ math
+ physics
+
+
+ political education
+ english
+
+
\ No newline at end of file
diff --git a/spring-all/README.md b/spring-all/README.md
index 47c947a414..0bbb600860 100644
--- a/spring-all/README.md
+++ b/spring-all/README.md
@@ -11,3 +11,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Properties with Spring](http://www.baeldung.com/2012/02/06/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage
- [Spring Profiles](http://www.baeldung.com/spring-profiles)
- [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor)
+- [What's New in Spring 4.3?](http://www.baeldung.com/whats-new-in-spring-4-3/)
diff --git a/spring-all/pom.xml b/spring-all/pom.xml
index 8ff09e5e17..5f14d32121 100644
--- a/spring-all/pom.xml
+++ b/spring-all/pom.xml
@@ -10,7 +10,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.2.6.RELEASE
+ 1.3.6.RELEASE
@@ -147,8 +147,38 @@
mockito-core
test
+
+
+ org.easymock
+ easymock
+ 3.4
+ test
+
+
+
+
+
+
+
+ org.springframework
+ spring-framework-bom
+ ${org.springframework.version}
+ pom
+ import
+
+
+
+ org.springframework
+ spring-core
+ ${org.springframework.version}
+
+
+
+
+
+
spring-all
@@ -217,7 +247,7 @@
- 4.2.5.RELEASE
+ 4.3.1.RELEASE
4.0.4.RELEASE
3.20.0-GA
1.2
diff --git a/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationsTestController.java b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationsTestController.java
new file mode 100644
index 0000000000..df1d173bd2
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationsTestController.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.attributeannotations;
+
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/test")
+public class AttributeAnnotationsTestController {
+
+ @GetMapping
+ public String get(@SessionAttribute String login, @RequestAttribute String query) {
+ return String.format("login = %s, query = %s", login, query);
+ }
+
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/ParamInterceptor.java b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/ParamInterceptor.java
new file mode 100644
index 0000000000..9cf6020a93
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/attributeannotations/ParamInterceptor.java
@@ -0,0 +1,17 @@
+package org.baeldung.spring43.attributeannotations;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public class ParamInterceptor extends HandlerInterceptorAdapter {
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ request.getSession().setAttribute("login", "john");
+ request.setAttribute("query", "invoices");
+ return super.preHandle(request, response, handler);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java b/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java
new file mode 100644
index 0000000000..4abd3cc813
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/cache/Foo.java
@@ -0,0 +1,29 @@
+package org.baeldung.spring43.cache;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Foo {
+
+ private static final Logger log = LoggerFactory.getLogger(Foo.class);
+
+ private static final AtomicInteger instanceCount = new AtomicInteger(0);
+
+
+ private final int instanceNum;
+
+ public Foo() {
+ instanceNum = instanceCount.incrementAndGet();
+ }
+
+ public static int getInstanceCount() {
+ return instanceCount.get();
+ }
+
+ public void printInstanceNumber() {
+ log.info("Foo instance number: {}", instanceNum);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/cache/FooService.java b/spring-all/src/main/java/org/baeldung/spring43/cache/FooService.java
new file mode 100644
index 0000000000..ad4c8b395f
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/cache/FooService.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.cache;
+
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FooService {
+
+ @Cacheable(cacheNames = "foos", sync = true)
+ public Foo getFoo(String id) {
+ return new Foo();
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/composedmapping/Appointment.java b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/Appointment.java
new file mode 100644
index 0000000000..af06249768
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/Appointment.java
@@ -0,0 +1,5 @@
+package org.baeldung.spring43.composedmapping;
+
+public class Appointment {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentService.java b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentService.java
new file mode 100644
index 0000000000..c4c5e82f65
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentService.java
@@ -0,0 +1,9 @@
+package org.baeldung.spring43.composedmapping;
+
+import java.util.Map;
+
+public interface AppointmentService {
+
+ Map getAppointmentsForToday();
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentsController.java b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentsController.java
new file mode 100644
index 0000000000..9f3c8729d8
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/composedmapping/AppointmentsController.java
@@ -0,0 +1,26 @@
+package org.baeldung.spring43.composedmapping;
+
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+@RequestMapping("/appointments")
+public class AppointmentsController {
+
+ private final AppointmentService appointmentService;
+
+ @Autowired
+ public AppointmentsController(AppointmentService appointmentService) {
+ this.appointmentService = appointmentService;
+ }
+
+ @GetMapping
+ public Map get() {
+ return appointmentService.getAppointmentsForToday();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/ctor/FooRepository.java b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooRepository.java
new file mode 100644
index 0000000000..96dbeb8642
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooRepository.java
@@ -0,0 +1,5 @@
+package org.baeldung.spring43.ctor;
+
+public class FooRepository {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/ctor/FooService.java b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooService.java
new file mode 100644
index 0000000000..bf92d1bd32
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/ctor/FooService.java
@@ -0,0 +1,15 @@
+package org.baeldung.spring43.ctor;
+
+public class FooService {
+
+ private final FooRepository repository;
+
+ public FooService(FooRepository repository) {
+ this.repository = repository;
+ }
+
+ public FooRepository getRepository() {
+ return repository;
+ }
+
+}
\ No newline at end of file
diff --git a/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/DateHolder.java b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/DateHolder.java
new file mode 100644
index 0000000000..9ae62cf484
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/DateHolder.java
@@ -0,0 +1,18 @@
+package org.baeldung.spring43.defaultmethods;
+
+import java.time.LocalDate;
+
+public class DateHolder implements IDateHolder {
+
+ private LocalDate localDate;
+
+ @Override
+ public LocalDate getLocalDate() {
+ return localDate;
+ }
+
+ @Override
+ public void setLocalDate(LocalDate localDate) {
+ this.localDate = localDate;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/IDateHolder.java b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/IDateHolder.java
new file mode 100644
index 0000000000..e37d27f9fc
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/defaultmethods/IDateHolder.java
@@ -0,0 +1,16 @@
+package org.baeldung.spring43.defaultmethods;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+public interface IDateHolder {
+
+ LocalDate getLocalDate();
+
+ void setLocalDate(LocalDate localDate);
+
+ default void setStringDate(String stringDate) {
+ setLocalDate(LocalDate.parse(stringDate, DateTimeFormatter.ofPattern("dd.MM.yyyy")));
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooRepository.java b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooRepository.java
new file mode 100644
index 0000000000..313f6fc8c5
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooRepository.java
@@ -0,0 +1,8 @@
+package org.baeldung.spring43.depresolution;
+
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class FooRepository {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooService.java b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooService.java
new file mode 100644
index 0000000000..b76fa84749
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/depresolution/FooService.java
@@ -0,0 +1,18 @@
+package org.baeldung.spring43.depresolution;
+
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.stereotype.Service;
+
+@Service
+public class FooService {
+
+ private final FooRepository repository;
+
+ public FooService(ObjectProvider repositoryProvider) {
+ this.repository = repositoryProvider.getIfUnique();
+ }
+
+ public FooRepository getRepository() {
+ return repository;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/AppPreferences.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/AppPreferences.java
new file mode 100644
index 0000000000..45b90c4609
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/AppPreferences.java
@@ -0,0 +1,10 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.ApplicationScope;
+
+@Component
+@ApplicationScope
+public class AppPreferences extends InstanceCountingService {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/InstanceCountingService.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/InstanceCountingService.java
new file mode 100644
index 0000000000..4fb90566d8
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/InstanceCountingService.java
@@ -0,0 +1,15 @@
+package org.baeldung.spring43.scopeannotations;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class InstanceCountingService {
+
+ private static final AtomicInteger instanceCount = new AtomicInteger(0);
+
+ private final int instanceNumber = instanceCount.incrementAndGet();
+
+ public int getInstanceNumber() {
+ return instanceNumber;
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/LoginAction.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/LoginAction.java
new file mode 100644
index 0000000000..60017b4b94
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/LoginAction.java
@@ -0,0 +1,10 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+@Component
+@RequestScope
+public class LoginAction extends InstanceCountingService {
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/ScopeTestController.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/ScopeTestController.java
new file mode 100644
index 0000000000..8f4390dfc0
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/ScopeTestController.java
@@ -0,0 +1,36 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/appointments")
+public class ScopeTestController {
+
+ @Autowired
+ private LoginAction loginAction;
+
+ @Autowired
+ private UserPreferences userPreferences;
+
+ @Autowired
+ private AppPreferences appPreferences;
+
+ @GetMapping("/request")
+ public String getRequestNumber() {
+ return Integer.toString(loginAction.getInstanceNumber());
+ }
+
+ @GetMapping("/session")
+ public String getSessionNumber() {
+ return Integer.toString(userPreferences.getInstanceNumber());
+ }
+
+ @GetMapping("/application")
+ public String getApplicationNumber() {
+ return Integer.toString(appPreferences.getInstanceNumber());
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/UserPreferences.java b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/UserPreferences.java
new file mode 100644
index 0000000000..ce49c4b1fe
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/spring43/scopeannotations/UserPreferences.java
@@ -0,0 +1,10 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.SessionScope;
+
+@Component
+@SessionScope
+public class UserPreferences extends InstanceCountingService {
+
+}
diff --git a/spring-all/src/main/resources/defaultmethods-context.xml b/spring-all/src/main/resources/defaultmethods-context.xml
new file mode 100644
index 0000000000..2b55037405
--- /dev/null
+++ b/spring-all/src/main/resources/defaultmethods-context.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-all/src/main/resources/implicit-ctor-context.xml b/spring-all/src/main/resources/implicit-ctor-context.xml
new file mode 100644
index 0000000000..c978ca17bd
--- /dev/null
+++ b/spring-all/src/main/resources/implicit-ctor-context.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
diff --git a/spring-all/src/main/resources/springAsync-config.xml b/spring-all/src/main/resources/springAsync-config.xml
index 8ed5f1319d..34e8b33f45 100644
--- a/spring-all/src/main/resources/springAsync-config.xml
+++ b/spring-all/src/main/resources/springAsync-config.xml
@@ -9,6 +9,6 @@
-
+
\ No newline at end of file
diff --git a/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationConfiguration.java
new file mode 100644
index 0000000000..97ae651473
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationConfiguration.java
@@ -0,0 +1,30 @@
+package org.baeldung.spring43.attributeannotations;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+@ComponentScan
+@EnableWebMvc
+public class AttributeAnnotationConfiguration extends WebMvcConfigurerAdapter {
+
+ @Bean
+ public ViewResolver viewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/WEB-INF/jsp/view/");
+ viewResolver.setSuffix(".jsp");
+ return viewResolver;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new ParamInterceptor());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java
new file mode 100644
index 0000000000..aa3acb113f
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/attributeannotations/AttributeAnnotationTest.java
@@ -0,0 +1,45 @@
+package org.baeldung.spring43.attributeannotations;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ContextConfiguration(classes = AttributeAnnotationConfiguration.class)
+@WebAppConfiguration
+public class AttributeAnnotationTest extends AbstractJUnit4SpringContextTests {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .build();
+ }
+
+ @Test
+ public void whenInterceptorAddsRequestAndSessionParams_thenParamsInjectedWithAttributesAnnotations() throws Exception {
+ String result = this.mockMvc.perform(get("/test")
+ .accept(MediaType.ALL))
+ .andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ Assert.assertEquals("login = john, query = invoices", result);
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsConfiguration.java
new file mode 100644
index 0000000000..e4610e5a83
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsConfiguration.java
@@ -0,0 +1,25 @@
+package org.baeldung.spring43.cache;
+
+import java.util.Collections;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.concurrent.ConcurrentMapCache;
+import org.springframework.cache.support.SimpleCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan
+@EnableCaching
+public class CacheRefinementsConfiguration {
+
+ @Bean
+ public CacheManager cacheManager() {
+ SimpleCacheManager manager = new SimpleCacheManager();
+ manager.setCaches(Collections.singletonList(new ConcurrentMapCache("foos")));
+ return manager;
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java
new file mode 100644
index 0000000000..bfd6e5047c
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/cache/CacheRefinementsTest.java
@@ -0,0 +1,31 @@
+package org.baeldung.spring43.cache;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertEquals;
+
+@ContextConfiguration(classes = CacheRefinementsConfiguration.class)
+public class CacheRefinementsTest extends AbstractJUnit4SpringContextTests {
+
+ private ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+ @Autowired
+ private FooService service;
+
+ @Test
+ public void whenMultipleThreadsExecuteCacheableMethodWithSyncTrue_thenMethodIsExecutedOnlyOnce() throws InterruptedException {
+ for (int i = 0; i < 10; i++) {
+ executorService.execute(() -> service.getFoo("test").printInstanceNumber());
+ }
+ executorService.awaitTermination(1, TimeUnit.SECONDS);
+ assertEquals(Foo.getInstanceCount(), 1);
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingConfiguration.java
new file mode 100644
index 0000000000..46bf3d8847
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingConfiguration.java
@@ -0,0 +1,36 @@
+package org.baeldung.spring43.composedmapping;
+
+import java.util.Collections;
+
+import org.easymock.EasyMock;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+import static org.easymock.EasyMock.*;
+
+@Configuration
+@ComponentScan
+@EnableWebMvc
+public class ComposedMappingConfiguration {
+
+ @Bean
+ public ViewResolver viewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/WEB-INF/jsp/view/");
+ viewResolver.setSuffix(".jsp");
+ return viewResolver;
+ }
+
+ @Bean
+ public AppointmentService appointmentBook() {
+ AppointmentService book = EasyMock.mock(AppointmentService.class);
+ EasyMock.expect(book.getAppointmentsForToday()).andReturn(Collections.emptyMap());
+ replay(book);
+ return book;
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java
new file mode 100644
index 0000000000..04fabbc834
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/composedmapping/ComposedMappingTest.java
@@ -0,0 +1,44 @@
+package org.baeldung.spring43.composedmapping;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.easymock.EasyMock.verify;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ContextConfiguration(classes = ComposedMappingConfiguration.class)
+@WebAppConfiguration
+public class ComposedMappingTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private AppointmentService appointmentService;
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .build();
+ }
+
+ @Test
+ public void whenRequestingMethodWithGetMapping_thenReceiving200Answer() throws Exception {
+ this.mockMvc.perform(get("/appointments")
+ .accept(MediaType.ALL))
+ .andExpect(status().isOk());
+ verify(appointmentService);
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java
new file mode 100644
index 0000000000..82caae15fe
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/ConfigurationConstructorInjectionTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.spring43.ctor;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertNotNull;
+
+@ContextConfiguration(classes = {FooRepositoryConfiguration.class, FooServiceConfiguration.class})
+public class ConfigurationConstructorInjectionTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ public FooService fooService;
+
+ @Test
+ public void whenSingleCtorInConfiguration_thenContextLoadsNormally() {
+ assertNotNull(fooService.getRepository());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/FooRepositoryConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooRepositoryConfiguration.java
new file mode 100644
index 0000000000..a05a36529f
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooRepositoryConfiguration.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.ctor;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FooRepositoryConfiguration {
+
+ @Bean
+ public FooRepository fooRepository() {
+ return new FooRepository();
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/FooServiceConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooServiceConfiguration.java
new file mode 100644
index 0000000000..41f1719320
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/FooServiceConfiguration.java
@@ -0,0 +1,19 @@
+package org.baeldung.spring43.ctor;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class FooServiceConfiguration {
+
+ private final FooRepository repository;
+
+ public FooServiceConfiguration(FooRepository repository) {
+ this.repository = repository;
+ }
+
+ @Bean
+ public FooService fooService() {
+ return new FooService(this.repository);
+ }
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java b/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java
new file mode 100644
index 0000000000..be0cf77a62
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/ctor/ImplicitConstructorTest.java
@@ -0,0 +1,21 @@
+package org.baeldung.spring43.ctor;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertNotNull;
+
+@ContextConfiguration("classpath:implicit-ctor-context.xml")
+public class ImplicitConstructorTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private FooService fooService;
+
+ @Test
+ public void whenBeanWithoutAutowiredCtor_thenInjectIntoSingleCtor() {
+ assertNotNull(fooService.getRepository());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java
new file mode 100644
index 0000000000..e29d89a679
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/DefaultMethodsInjectionTest.java
@@ -0,0 +1,23 @@
+package org.baeldung.spring43.defaultmethods;
+
+import java.time.LocalDate;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertEquals;
+
+@ContextConfiguration("classpath:defaultmethods-context.xml")
+public class DefaultMethodsInjectionTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private IDateHolder dateHolder;
+
+ @Test
+ public void whenInjectingToDefaultInterfaceMethod_thenInjectionShouldHappen() {
+ assertEquals(LocalDate.of(1982, 10, 15), dateHolder.getLocalDate());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/ITransactionalTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/ITransactionalTest.java
new file mode 100644
index 0000000000..c7b95bced4
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/ITransactionalTest.java
@@ -0,0 +1,22 @@
+package org.baeldung.spring43.defaultmethods;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+
+public interface ITransactionalTest {
+
+ Logger log = LoggerFactory.getLogger(ITransactionalTest.class);
+
+ @BeforeTransaction
+ default void beforeTransaction() {
+ log.info("Opening transaction");
+ }
+
+ @AfterTransaction
+ default void afterTransaction() {
+ log.info("Closing transaction");
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java
new file mode 100644
index 0000000000..89c96ba1d4
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTest.java
@@ -0,0 +1,14 @@
+package org.baeldung.spring43.defaultmethods;
+
+import org.junit.Test;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
+
+@ContextConfiguration(classes = TransactionalTestConfiguration.class)
+public class TransactionalTest extends AbstractTransactionalJUnit4SpringContextTests implements ITransactionalTest {
+
+ @Test
+ public void whenDefaultMethodAnnotatedWithBeforeTransaction_thenDefaultMethodIsExecuted() {
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java
new file mode 100644
index 0000000000..946b19d00d
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/defaultmethods/TransactionalTestConfiguration.java
@@ -0,0 +1,30 @@
+package org.baeldung.spring43.defaultmethods;
+
+
+import javax.sql.DataSource;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.jdbc.datasource.SimpleDriverDataSource;
+import org.springframework.transaction.PlatformTransactionManager;
+
+@Configuration
+public class TransactionalTestConfiguration {
+
+ @Bean
+ public DataSource getDataSource() {
+ SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
+ simpleDriverDataSource.setDriverClass(org.hsqldb.jdbcDriver.class);
+ simpleDriverDataSource.setUrl("jdbc:hsqldb:mem:app-db");
+ simpleDriverDataSource.setUsername("sa");
+ simpleDriverDataSource.setPassword("");
+ return simpleDriverDataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return new DataSourceTransactionManager(getDataSource());
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderConfiguration.java
new file mode 100644
index 0000000000..530c4d9f4a
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderConfiguration.java
@@ -0,0 +1,9 @@
+package org.baeldung.spring43.depresolution;
+
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan
+public class ObjectProviderConfiguration {
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java
new file mode 100644
index 0000000000..eeeb005f81
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/depresolution/ObjectProviderTest.java
@@ -0,0 +1,23 @@
+package org.baeldung.spring43.depresolution;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import static org.junit.Assert.assertNotNull;
+
+@ContextConfiguration(classes = ObjectProviderConfiguration.class)
+public class ObjectProviderTest extends AbstractJUnit4SpringContextTests {
+
+ @Autowired
+ private FooService fooService;
+
+ @Test
+ public void whenArgumentIsObjectProvider_thenObjectProviderInjected() {
+
+ assertNotNull(fooService.getRepository());
+
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsConfiguration.java b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsConfiguration.java
new file mode 100644
index 0000000000..24c1ec2f34
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsConfiguration.java
@@ -0,0 +1,23 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+@ComponentScan
+@EnableWebMvc
+public class ScopeAnnotationsConfiguration {
+
+ @Bean
+ public ViewResolver viewResolver() {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/WEB-INF/jsp/view/");
+ viewResolver.setSuffix(".jsp");
+ return viewResolver;
+ }
+
+}
diff --git a/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java
new file mode 100644
index 0000000000..b696760f68
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/spring43/scopeannotations/ScopeAnnotationsTest.java
@@ -0,0 +1,110 @@
+package org.baeldung.spring43.scopeannotations;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@ContextConfiguration(classes = ScopeAnnotationsConfiguration.class)
+@WebAppConfiguration
+public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
+ .build();
+ }
+
+ @Test
+ public void whenDifferentRequests_thenDifferentInstancesOfRequestScopedBeans() throws Exception {
+ MockHttpSession session = new MockHttpSession();
+
+ String requestScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/request")
+ .session(session)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ String requestScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/request")
+ .session(session)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ assertNotEquals(requestScopedServiceInstanceNumber1, requestScopedServiceInstanceNumber2);
+ }
+
+ @Test
+ public void whenDifferentSessions_thenDifferentInstancesOfSessionScopedBeans() throws Exception {
+
+ MockHttpSession session1 = new MockHttpSession();
+ MockHttpSession session2 = new MockHttpSession();
+
+ String sessionScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/session")
+ .session(session1)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ String sessionScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/session")
+ .session(session1)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ String sessionScopedServiceInstanceNumber3 = this.mockMvc.perform(get("/appointments/session")
+ .session(session2)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ assertEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber2);
+
+ assertNotEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber3);
+
+ }
+
+ @Test
+ public void whenDifferentSessionsAndRequests_thenAlwaysSingleApplicationScopedBean() throws Exception {
+
+ MockHttpSession session1 = new MockHttpSession();
+ MockHttpSession session2 = new MockHttpSession();
+
+ String applicationScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/application")
+ .session(session1)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+ String applicationScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/application")
+ .session(session2)
+ .accept(MediaType.ALL)).andExpect(status().isOk())
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ assertEquals(applicationScopedServiceInstanceNumber1, applicationScopedServiceInstanceNumber2);
+
+ }
+
+}
diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml
index 368dfa19c1..4ac008cfc8 100644
--- a/spring-boot/pom.xml
+++ b/spring-boot/pom.xml
@@ -60,6 +60,26 @@
spring-boot-starter-test
test
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ com.jayway.jsonpath
+ json-path
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.subethamail
+ subethasmtp
+ 3.1.7
+ test
+
diff --git a/spring-boot/src/main/java/org/baeldung/Application.java b/spring-boot/src/main/java/org/baeldung/Application.java
new file mode 100644
index 0000000000..aae0c427a9
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/Application.java
@@ -0,0 +1,13 @@
+package org.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.context.ApplicationContext;
+
+@org.springframework.boot.autoconfigure.SpringBootApplication
+public class Application {
+ private static ApplicationContext applicationContext;
+
+ public static void main(String[] args) {
+ applicationContext = SpringApplication.run(Application.class, args);
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
new file mode 100644
index 0000000000..b6f88e7cd5
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java
@@ -0,0 +1,38 @@
+package org.baeldung.controller;
+
+import org.baeldung.domain.GenericEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+public class GenericEntityController {
+ private List entityList = new ArrayList<>();
+
+ {
+ entityList.add(new GenericEntity(1l, "entity_1"));
+ entityList.add(new GenericEntity(2l, "entity_2"));
+ entityList.add(new GenericEntity(3l, "entity_3"));
+ entityList.add(new GenericEntity(4l, "entity_4"));
+ }
+
+ @RequestMapping("/entity/all")
+ public List findAll() {
+ return entityList;
+ }
+
+ @RequestMapping(value = "/entity", method = RequestMethod.POST)
+ public GenericEntity addEntity(GenericEntity entity) {
+ entityList.add(entity);
+ return entity;
+ }
+
+ @RequestMapping("/entity/findby/{id}")
+ public GenericEntity findById(@PathVariable Long id) {
+ return entityList.stream().filter(entity -> entity.getId().equals(id)).findFirst().get();
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java b/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java
new file mode 100644
index 0000000000..7b1d27cb66
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java
@@ -0,0 +1,42 @@
+package org.baeldung.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class GenericEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+ private String value;
+
+ public GenericEntity() {
+ }
+
+ public GenericEntity(String value) {
+ this.value = value;
+ }
+
+ public GenericEntity(Long id, String value) {
+ this.id = id;
+ this.value = value;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java b/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java
new file mode 100644
index 0000000000..7bb1e6dcdc
--- /dev/null
+++ b/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java
@@ -0,0 +1,7 @@
+package org.baeldung.repository;
+
+import org.baeldung.domain.GenericEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface GenericEntityRepository extends JpaRepository {
+}
diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties
index 8ee0ed29bc..78bcf4cc05 100644
--- a/spring-boot/src/main/resources/application.properties
+++ b/spring-boot/src/main/resources/application.properties
@@ -1,4 +1,4 @@
-server.port=8083
+server.port=8080
server.contextPath=/springbootapp
management.port=8081
management.address=127.0.0.1
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java
new file mode 100644
index 0000000000..ac7bcd62a9
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationTest.java
@@ -0,0 +1,52 @@
+package org.baeldung;
+
+import org.baeldung.domain.GenericEntity;
+import org.baeldung.repository.GenericEntityRepository;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.nio.charset.Charset;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+@WebAppConfiguration
+public class SpringBootApplicationTest {
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+ private MockMvc mockMvc;
+
+
+ @Before
+ public void setupMockMvc() {
+ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
+ .build();
+ }
+
+ @Test
+ public void givenRequestHasBeenMade_whenMeetsAllOfGivenConditions_thenCorrect() throws Exception {
+ MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
+ MediaType.APPLICATION_JSON.getSubtype(),
+ Charset.forName("utf8"));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")).
+ andExpect(MockMvcResultMatchers.status().isOk()).
+ andExpect(MockMvcResultMatchers.content().contentType(contentType)).
+ andExpect(jsonPath("$", hasSize(4)));
+ }
+}
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java b/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java
new file mode 100644
index 0000000000..8a6b5139fe
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootJPATest.java
@@ -0,0 +1,27 @@
+package org.baeldung;
+
+import org.baeldung.domain.GenericEntity;
+import org.baeldung.repository.GenericEntityRepository;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+public class SpringBootJPATest {
+ @Autowired
+ private GenericEntityRepository genericEntityRepository;
+
+ @Test
+ public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
+ GenericEntity genericEntity = genericEntityRepository.save(new GenericEntity("test"));
+ GenericEntity foundedEntity = genericEntityRepository.findOne(genericEntity.getId());
+ assertNotNull(foundedEntity);
+ assertEquals(genericEntity.getValue(), foundedEntity.getValue());
+ }
+}
diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java
new file mode 100644
index 0000000000..2e436ece2e
--- /dev/null
+++ b/spring-boot/src/test/java/org/baeldung/SpringBootMailTest.java
@@ -0,0 +1,82 @@
+package org.baeldung;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.SpringApplicationConfiguration;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.context.WebApplicationContext;
+import org.subethamail.wiser.Wiser;
+import org.subethamail.wiser.WiserMessage;
+
+import javax.mail.MessagingException;
+import java.io.IOException;
+import java.util.List;
+
+import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = Application.class)
+public class SpringBootMailTest {
+ @Autowired
+ private JavaMailSender javaMailSender;
+
+ private Wiser wiser;
+
+ private String userTo = "user2@localhost";
+ private String userFrom = "user1@localhost";
+ private String subject = "Test subject";
+ private String textMail = "Text subject mail";
+
+ @Before
+ public void setUp() throws Exception {
+ final int TEST_PORT = 25;
+ wiser = new Wiser(TEST_PORT);
+ wiser.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ wiser.stop();
+ }
+
+ @Test
+ public void givenMail_whenSendAndReceived_thenCorrect() throws Exception {
+ SimpleMailMessage message = composeEmailMessage();
+ javaMailSender.send(message);
+ List messages = wiser.getMessages();
+
+ assertThat(messages, hasSize(1));
+ WiserMessage wiserMessage = messages.get(0);
+ assertEquals(userFrom, wiserMessage.getEnvelopeSender());
+ assertEquals(userTo, wiserMessage.getEnvelopeReceiver());
+ assertEquals(subject, getSubject(wiserMessage));
+ assertEquals(textMail, getMessage(wiserMessage));
+ }
+
+ private String getMessage(WiserMessage wiserMessage) throws MessagingException, IOException {
+ return wiserMessage.getMimeMessage().getContent().toString().trim();
+ }
+
+ private String getSubject(WiserMessage wiserMessage) throws MessagingException {
+ return wiserMessage.getMimeMessage().getSubject();
+ }
+
+
+ private SimpleMailMessage composeEmailMessage() {
+ SimpleMailMessage mailMessage = new SimpleMailMessage();
+ mailMessage.setTo(userTo);
+ mailMessage.setReplyTo(userFrom);
+ mailMessage.setFrom(userFrom);
+ mailMessage.setSubject(subject);
+ mailMessage.setText(textMail);
+ return mailMessage;
+ }
+}
diff --git a/spring-boot/src/test/resources/application.properties b/spring-boot/src/test/resources/application.properties
new file mode 100644
index 0000000000..bcfcf4b2fb
--- /dev/null
+++ b/spring-boot/src/test/resources/application.properties
@@ -0,0 +1,3 @@
+spring.mail.host=localhost
+spring.mail.port=25
+spring.mail.properties.mail.smtp.auth=false
\ No newline at end of file
diff --git a/spring-controller/pom.xml b/spring-controller/pom.xml
new file mode 100644
index 0000000000..d9fd79c095
--- /dev/null
+++ b/spring-controller/pom.xml
@@ -0,0 +1,56 @@
+
+ 4.0.0
+ test
+ spring-controller
+ 0.0.1-SNAPSHOT
+ war
+
+
+
+ org.springframework
+ spring-webmvc
+ 4.3.0.RELEASE
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.0.1
+ compile
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.6.3
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.6.3
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.6.3
+
+
+ org.springframework
+ spring-web
+ 4.3.0.RELEASE
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.springframework
+ spring-test
+ 4.2.6.RELEASE
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-controller/src/main/java/com/baledung/controller/RestAnnotatedController.java b/spring-controller/src/main/java/com/baledung/controller/RestAnnotatedController.java
new file mode 100644
index 0000000000..15f9ba14d4
--- /dev/null
+++ b/spring-controller/src/main/java/com/baledung/controller/RestAnnotatedController.java
@@ -0,0 +1,19 @@
+package com.baledung.controller;
+
+import com.baledung.student.Student;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class RestAnnotatedController {
+
+ @GetMapping(value = "/annotated/student/{studentId}")
+ public Student getData(@PathVariable Integer studentId) {
+ Student student = new Student();
+ student.setName("Peter");
+ student.setId(studentId);
+
+ return student;
+ }
+}
diff --git a/spring-controller/src/main/java/com/baledung/controller/RestController.java b/spring-controller/src/main/java/com/baledung/controller/RestController.java
new file mode 100644
index 0000000000..e9afa88471
--- /dev/null
+++ b/spring-controller/src/main/java/com/baledung/controller/RestController.java
@@ -0,0 +1,21 @@
+package com.baledung.controller;
+
+import com.baledung.student.Student;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+@Controller
+public class RestController{
+
+ @GetMapping(value="/student/{studentId}")
+ public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
+ Student student = new Student();
+ student.setName("Peter");
+ student.setId(studentId);
+
+ return student;
+
+ }
+}
diff --git a/spring-controller/src/main/java/com/baledung/controller/TestController.java b/spring-controller/src/main/java/com/baledung/controller/TestController.java
new file mode 100644
index 0000000000..8a9939b371
--- /dev/null
+++ b/spring-controller/src/main/java/com/baledung/controller/TestController.java
@@ -0,0 +1,24 @@
+
+/**
+ * @author Prashant Dutta
+ */
+package com.baledung.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+@RequestMapping(value = "/test")
+public class TestController {
+
+ @GetMapping
+ public ModelAndView getTestData() {
+ ModelAndView mv = new ModelAndView();
+ mv.setViewName("welcome");
+ mv.getModel().put("data", "Welcome home man");
+
+ return mv;
+ }
+}
\ No newline at end of file
diff --git a/spring-controller/src/main/java/com/baledung/student/Student.java b/spring-controller/src/main/java/com/baledung/student/Student.java
new file mode 100644
index 0000000000..7a5606415f
--- /dev/null
+++ b/spring-controller/src/main/java/com/baledung/student/Student.java
@@ -0,0 +1,33 @@
+package com.baledung.student;
+
+public class Student {
+ private String name;
+
+ private int id;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public int hashCode(){
+ return this.id;
+ }
+
+ @Override
+ public boolean equals(Object obj){
+ return this.name.equals(((Student)obj).getName());
+ }
+}
\ No newline at end of file
diff --git a/spring-controller/src/main/resources/test-mvc.xml b/spring-controller/src/main/resources/test-mvc.xml
new file mode 100644
index 0000000000..fec69e2dec
--- /dev/null
+++ b/spring-controller/src/main/resources/test-mvc.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ /WEB-INF/
+
+
+ .jsp
+
+
+
\ No newline at end of file
diff --git a/spring-controller/src/main/webapp/WEB-INF/web.xml b/spring-controller/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..4e0e7a231c
--- /dev/null
+++ b/spring-controller/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,27 @@
+
+
+
+ test-mvc
+
+ org.springframework.web.servlet.DispatcherServlet
+
+ 1
+
+ contextConfigLocation
+ /WEB-INF/test-mvc.xml
+
+
+
+
+ test-mvc
+ /test/*
+
+
+
+ /WEB-INF/index.jsp
+
+
diff --git a/spring-controller/src/main/webapp/WEB-INF/welcome.jsp b/spring-controller/src/main/webapp/WEB-INF/welcome.jsp
new file mode 100644
index 0000000000..61ee4bc7d6
--- /dev/null
+++ b/spring-controller/src/main/webapp/WEB-INF/welcome.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+
+
+
+
+Insert title here
+
+
+Data returned is ${data}
+
+
\ No newline at end of file
diff --git a/spring-controller/src/test/java/com/baledung/test/ControllerTest.java b/spring-controller/src/test/java/com/baledung/test/ControllerTest.java
new file mode 100644
index 0000000000..7f56d09112
--- /dev/null
+++ b/spring-controller/src/test/java/com/baledung/test/ControllerTest.java
@@ -0,0 +1,83 @@
+package com.baledung.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.baledung.student.Student;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration({"classpath:test-mvc.xml"})
+public class ControllerTest {
+
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ private Student selectedStudent;
+
+ @Before
+ public void setUp() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
+
+ selectedStudent = new Student();
+ selectedStudent.setId(1);
+ selectedStudent.setName("Peter");
+ }
+
+ @Test
+ public void testTestController() throws Exception {
+
+ ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/"))
+ .andReturn()
+ .getModelAndView();
+
+ // validate modal data
+ Assert.assertSame(mv.getModelMap().get("data").toString(), "Welcome home man");
+
+ // validate view name
+ Assert.assertSame(mv.getViewName(), "welcome");
+ }
+
+ @Test
+ public void testRestController() throws Exception {
+
+ String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/student/{studentId}", 1))
+ .andReturn().getResponse()
+ .getContentAsString();
+
+ ObjectMapper reader = new ObjectMapper();
+
+ Student studentDetails = reader.readValue(responseBody, Student.class);
+
+ Assert.assertEquals(selectedStudent, studentDetails);
+
+ }
+
+ @Test
+ public void testRestAnnotatedController() throws Exception {
+
+ String responseBody = this.mockMvc.perform(MockMvcRequestBuilders.get("/annotated/student/{studentId}", 1))
+ .andReturn().getResponse()
+ .getContentAsString();
+
+ ObjectMapper reader = new ObjectMapper();
+
+ Student studentDetails = reader.readValue(responseBody, Student.class);
+
+ Assert.assertEquals(selectedStudent, studentDetails);
+ }
+}