diff --git a/annotations/annotation-processing/pom.xml b/annotations/annotation-processing/pom.xml
new file mode 100644
index 0000000000..6d07394b87
--- /dev/null
+++ b/annotations/annotation-processing/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ annotations
+ ../
+
+
+ annotation-processing
+
+
+ 1.0-rc2
+ 3.5.1
+
+
+
+
+
+ com.google.auto.service
+ auto-service
+ ${auto-service.version}
+ provided
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java
new file mode 100644
index 0000000000..0883e108e7
--- /dev/null
+++ b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java
@@ -0,0 +1,132 @@
+package com.baeldung.annotation.processor;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+import com.google.auto.service.AutoService;
+
+@SupportedAnnotationTypes("com.baeldung.annotation.processor.BuilderProperty")
+@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@AutoService(Processor.class)
+public class BuilderProcessor extends AbstractProcessor {
+
+ @Override
+ public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ for (TypeElement annotation : annotations) {
+
+ Set extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
+
+ Map> annotatedMethods = annotatedElements.stream()
+ .collect(Collectors.partitioningBy(element ->
+ ((ExecutableType) element.asType()).getParameterTypes().size() == 1
+ && element.getSimpleName().toString().startsWith("set")));
+
+ List setters = annotatedMethods.get(true);
+ List otherMethods = annotatedMethods.get(false);
+
+ otherMethods.forEach(element ->
+ processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
+ "@BuilderProperty must be applied to a setXxx method with a single argument", element));
+
+ if (setters.isEmpty()) {
+ continue;
+ }
+
+ String className = ((TypeElement) setters.get(0).getEnclosingElement()).getQualifiedName().toString();
+
+ Map setterMap = setters.stream().collect(Collectors.toMap(
+ setter -> setter.getSimpleName().toString(),
+ setter -> ((ExecutableType) setter.asType())
+ .getParameterTypes().get(0).toString()
+ ));
+
+ try {
+ writeBuilderFile(className, setterMap);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ return true;
+ }
+
+ private void writeBuilderFile(String className, Map setterMap) throws IOException {
+
+ String packageName = null;
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot > 0) {
+ packageName = className.substring(0, lastDot);
+ }
+
+ String simpleClassName = className.substring(lastDot + 1);
+ String builderClassName = className + "Builder";
+ String builderSimpleClassName = builderClassName.substring(lastDot + 1);
+
+ JavaFileObject builderFile = processingEnv.getFiler().createSourceFile(builderClassName);
+ try (PrintWriter out = new PrintWriter(builderFile.openWriter())) {
+
+ if (packageName != null) {
+ out.print("package ");
+ out.print(packageName);
+ out.println(";");
+ out.println();
+ }
+
+ out.print("public class ");
+ out.print(builderSimpleClassName);
+ out.println(" {");
+ out.println();
+
+ out.print(" private ");
+ out.print(simpleClassName);
+ out.print(" object = new ");
+ out.print(simpleClassName);
+ out.println("();");
+ out.println();
+
+ out.print(" public ");
+ out.print(simpleClassName);
+ out.println(" build() {");
+ out.println(" return object;");
+ out.println(" }");
+ out.println();
+
+ setterMap.entrySet().forEach(setter -> {
+ String methodName = setter.getKey();
+ String argumentType = setter.getValue();
+
+ out.print(" public ");
+ out.print(builderSimpleClassName);
+ out.print(" ");
+ out.print(methodName);
+
+ out.print("(");
+
+ out.print(argumentType);
+ out.println(" value) {");
+ out.print(" object.");
+ out.print(methodName);
+ out.println("(value);");
+ out.println(" return this;");
+ out.println(" }");
+ out.println();
+ });
+
+ out.println("}");
+
+ }
+ }
+
+}
diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java
new file mode 100644
index 0000000000..84fcc73850
--- /dev/null
+++ b/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java
@@ -0,0 +1,8 @@
+package com.baeldung.annotation.processor;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface BuilderProperty {
+}
diff --git a/annotations/annotation-user/pom.xml b/annotations/annotation-user/pom.xml
new file mode 100644
index 0000000000..f76f691f93
--- /dev/null
+++ b/annotations/annotation-user/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+
+
+ annotations
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../
+
+
+ annotation-user
+
+
+
+
+ com.baeldung
+ annotation-processing
+ ${project.parent.version}
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.5.1
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java b/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java
new file mode 100644
index 0000000000..23787ba4f4
--- /dev/null
+++ b/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java
@@ -0,0 +1,29 @@
+package com.baeldung.annotation;
+
+import com.baeldung.annotation.processor.BuilderProperty;
+
+public class Person {
+
+ private int age;
+
+ private String name;
+
+ public int getAge() {
+ return age;
+ }
+
+ @BuilderProperty
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @BuilderProperty
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java b/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java
new file mode 100644
index 0000000000..72f9ac8bc7
--- /dev/null
+++ b/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.annotation;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class PersonBuilderTest {
+
+ @Test
+ public void whenBuildPersonWithBuilder_thenObjectHasPropertyValues() {
+
+ Person person = new PersonBuilder()
+ .setAge(25)
+ .setName("John")
+ .build();
+
+ assertEquals(25, person.getAge());
+ assertEquals("John", person.getName());
+
+ }
+
+}
diff --git a/spring-cloud/spring-cloud-integration/pom.xml b/annotations/pom.xml
similarity index 55%
rename from spring-cloud/spring-cloud-integration/pom.xml
rename to annotations/pom.xml
index 1d56995009..f691674cf1 100644
--- a/spring-cloud/spring-cloud-integration/pom.xml
+++ b/annotations/pom.xml
@@ -2,14 +2,19 @@
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
4.0.0
- com.baeldung.spring.cloud
- spring-cloud-integration
- 1.0.0-SNAPSHOT
+ annotations
pom
- part-1
+ annotation-processing
+ annotation-user
+
\ No newline at end of file
diff --git a/core-java-8/README.md b/core-java-8/README.md
index e6bac2a4c9..c130e6bd41 100644
--- a/core-java-8/README.md
+++ b/core-java-8/README.md
@@ -11,4 +11,14 @@
- [Lambda Expressions and Functional Interfaces: Tips and Best Practices](http://www.baeldung.com/java-8-lambda-expressions-tips)
- [The Double Colon Operator in Java 8](http://www.baeldung.com/java-8-double-colon-operator)
- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams)
-- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
\ No newline at end of file
+- [Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
+- [Convert String to int or Integer in Java](http://www.baeldung.com/java-convert-string-to-int-or-integer)
+- [Convert char to String in Java](http://www.baeldung.com/java-convert-char-to-string)
+- [Guide to Java 8’s Functional Interfaces](http://www.baeldung.com/java-8-functional-interfaces)
+- [Guide To CompletableFuture](http://www.baeldung.com/java-completablefuture)
+- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava)
+- [Guide to Java 8 Collectors](http://www.baeldung.com/java-8-collectors)
+- [The Java 8 Stream API Tutorial](http://www.baeldung.com/java-8-streams)
+- [New Features in Java 8](http://www.baeldung.com/java-8-new-features)
+- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction)
+- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml
index 63df0e1b95..566eb4e43a 100644
--- a/core-java-8/pom.xml
+++ b/core-java-8/pom.xml
@@ -1,9 +1,10 @@
4.0.0
+
com.baeldung
+ 1.0.0-SNAPSHOT
core-java8
- 0.1-SNAPSHOT
core-java8
@@ -111,6 +112,9 @@
+
+ UTF-8
+
1.7.13
1.0.13
diff --git a/core-java-8/src/main/resources/fileTest.txt b/core-java-8/src/main/resources/fileTest.txt
new file mode 100644
index 0000000000..ce4bea208b
--- /dev/null
+++ b/core-java-8/src/main/resources/fileTest.txt
@@ -0,0 +1 @@
+Hello World from fileTest.txt!!!
\ No newline at end of file
diff --git a/core-java-8/src/test/java/com/baeldung/file/FileOperationsTest.java b/core-java-8/src/test/java/com/baeldung/file/FileOperationsTest.java
new file mode 100644
index 0000000000..b1476b6360
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/file/FileOperationsTest.java
@@ -0,0 +1,78 @@
+package com.baeldung.file;
+
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+
+import static org.hamcrest.CoreMatchers.containsString;
+
+public class FileOperationsTest {
+
+ @Test
+ public void givenFileName_whenUsingClassloader_thenFileData() throws IOException {
+ String expectedData = "Hello World from fileTest.txt!!!";
+
+ ClassLoader classLoader = getClass().getClassLoader();
+ InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+}
+
+ @Test
+ public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() throws IOException {
+ String expectedData = "Hello World from fileTest.txt!!!";
+
+ Class clazz = FileOperationsTest.class;
+ InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+ }
+
+ @Test
+ public void givenURLName_whenUsingURL_thenFileData() throws IOException {
+ String expectedData = "Baeldung";
+
+ URL urlObject = new URL("http://www.baeldung.com/");
+ URLConnection urlConnection = urlObject.openConnection();
+
+ InputStream inputStream = urlConnection.getInputStream();
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+ }
+
+ @Test
+ public void givenFileName_whenUsingJarFile_thenFileData() throws IOException {
+ String expectedData = "BSD License";
+
+ Class clazz = Matchers.class;
+ InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
+ String data = readFromInputStream(inputStream);
+
+ Assert.assertThat(data, containsString(expectedData));
+ }
+
+ private String readFromInputStream(InputStream inputStream) throws IOException {
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+ BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+ StringBuilder resultStringBuilder = new StringBuilder();
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ resultStringBuilder.append(line);
+ resultStringBuilder.append("\n");
+ }
+ bufferedReader.close();
+ inputStreamReader.close();
+ inputStream.close();
+ return resultStringBuilder.toString();
+ }
+}
\ No newline at end of file
diff --git a/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java b/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java
index efd548a4b1..f2e7452137 100644
--- a/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java
+++ b/core-java-8/src/test/java/com/baeldung/java8/JavaFolderSizeTest.java
@@ -21,7 +21,7 @@ public class JavaFolderSizeTest {
@Before
public void init() {
final String separator = File.separator;
- path = "src" + separator + "test" + separator + "resources";
+ path = String.format("src%stest%sresources", separator, separator);
}
@Test
@@ -79,7 +79,9 @@ public class JavaFolderSizeTest {
final File folder = new File(path);
final Iterable files = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder);
- final long size = StreamSupport.stream(files.spliterator(), false).filter(f -> f.isFile()).mapToLong(File::length).sum();
+ final long size = StreamSupport.stream(files.spliterator(), false)
+ .filter(File::isFile)
+ .mapToLong(File::length).sum();
assertEquals(expectedSize, size);
}
@@ -101,13 +103,11 @@ public class JavaFolderSizeTest {
long length = 0;
final File[] files = folder.listFiles();
- final int count = files.length;
-
- for (int i = 0; i < count; i++) {
- if (files[i].isFile()) {
- length += files[i].length();
+ for (File file : files) {
+ if (file.isFile()) {
+ length += file.length();
} else {
- length += getFolderSize(files[i]);
+ length += getFolderSize(file);
}
}
return length;
diff --git a/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeTest.java b/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeTest.java
new file mode 100644
index 0000000000..06d9394a5e
--- /dev/null
+++ b/core-java-8/src/test/java/com/baeldung/util/CurrentDateTimeTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.junit.Test;
+
+public class CurrentDateTimeTest {
+
+ @Test
+ public void shouldReturnCurrentDate() {
+
+ final LocalDate now = LocalDate.now();
+ final Calendar calendar = GregorianCalendar.getInstance();
+
+ assertEquals("10-10-2010".length(), now.toString().length());
+ assertEquals(calendar.get(Calendar.DATE), now.get(ChronoField.DAY_OF_MONTH));
+ assertEquals(calendar.get(Calendar.MONTH), now.get(ChronoField.MONTH_OF_YEAR) - 1);
+ assertEquals(calendar.get(Calendar.YEAR), now.get(ChronoField.YEAR));
+ }
+
+ @Test
+ public void shouldReturnCurrentTime() {
+
+ final LocalTime now = LocalTime.now();
+ final Calendar calendar = GregorianCalendar.getInstance();
+
+ assertEquals(calendar.get(Calendar.HOUR_OF_DAY), now.get(ChronoField.HOUR_OF_DAY));
+ assertEquals(calendar.get(Calendar.MINUTE), now.get(ChronoField.MINUTE_OF_HOUR));
+ assertEquals(calendar.get(Calendar.SECOND), now.get(ChronoField.SECOND_OF_MINUTE));
+ }
+
+ @Test
+ public void shouldReturnCurrentTimestamp() {
+
+ final Instant now = Instant.now();
+ final Calendar calendar = GregorianCalendar.getInstance();
+
+ assertEquals(calendar.getTimeInMillis() / 1000, now.getEpochSecond());
+ }
+}
diff --git a/core-java-8/src/test/resources/.gitignore b/core-java-8/src/test/resources/.gitignore
deleted file mode 100644
index 83c05e60c8..0000000000
--- a/core-java-8/src/test/resources/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-*.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-8/src/test/resources/test.txt b/core-java-8/src/test/resources/test.txt
new file mode 100644
index 0000000000..652d70630f
--- /dev/null
+++ b/core-java-8/src/test/resources/test.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse facilisis neque sed turpis venenatis, non dignissim risus volutpat.
\ No newline at end of file
diff --git a/core-java-9/pom.xml b/core-java-9/pom.xml
index b29838d283..844ad6a782 100644
--- a/core-java-9/pom.xml
+++ b/core-java-9/pom.xml
@@ -60,12 +60,8 @@
1.9
1.9
-
true
-
-
@@ -85,12 +81,7 @@
-
- 3.6-jigsaw-SNAPSHOT
-
-
+ 3.6-jigsaw-SNAPSHOT
2.19.1
diff --git a/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java
index 102ceda18f..b0684a94f8 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java
+++ b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalsStreamTest.java
@@ -42,6 +42,19 @@ public class Java9OptionalsStreamTest {
assertEquals("bar", filteredList.get(1));
}
+ @Test
+ public void filterOutPresentOptionalsWithFlatMap2() {
+ assertEquals(4, listOfOptionals.size());
+
+ List filteredList = listOfOptionals.stream()
+ .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
+ .collect(Collectors.toList());
+ assertEquals(2, filteredList.size());
+
+ assertEquals("foo", filteredList.get(0));
+ assertEquals("bar", filteredList.get(1));
+ }
+
@Test
public void filterOutPresentOptionalsWithJava9() {
assertEquals(4, listOfOptionals.size());
diff --git a/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java b/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java
index d6c16b91bc..a00646e4db 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java
+++ b/core-java-9/src/test/java/com/baeldung/java9/MultiResultionImageTest.java
@@ -1,6 +1,5 @@
package com.baeldung.java9;
-
-import static org.junit.Assert.assertTrue;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
diff --git a/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java b/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java
new file mode 100644
index 0000000000..56b4bb7b8c
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/OptionalToStreamTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.java9;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class OptionalToStreamTest {
+
+ @Test
+ public void testOptionalToStream() {
+ Optional op = Optional.ofNullable("String value");
+ Stream strOptionalStream = op.stream();
+ Stream filteredStream = strOptionalStream.filter((str) -> {
+ return str != null && str.startsWith("String");
+ });
+ assertEquals(1, filteredStream.count());
+
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java b/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java
new file mode 100644
index 0000000000..0f8db83d9c
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/SetExamplesTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.java9;
+
+import java.util.Set;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SetExamplesTest {
+
+ @Test
+ public void testUnmutableSet() {
+ Set strKeySet = Set.of("key1", "key2", "key3");
+ try {
+ strKeySet.add("newKey");
+ } catch (UnsupportedOperationException uoe) {
+ }
+ assertEquals(strKeySet.size(), 3);
+ }
+
+ @Test
+ public void testArrayToSet() {
+ Integer[] intArray = new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
+ Set intSet = Set.of(intArray);
+ assertEquals(intSet.size(), intArray.length);
+ }
+}
diff --git a/core-java/pom.xml b/core-java/pom.xml
index bc533607e7..bce97d1148 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -123,6 +123,12 @@
${mockito.version}
test
+
+
+ commons-codec
+ commons-codec
+ 1.10
+
diff --git a/core-java/src/main/java/com/baeldung/java/regex/Result.java b/core-java/src/main/java/com/baeldung/java/regex/Result.java
new file mode 100644
index 0000000000..d47c94ad2e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/java/regex/Result.java
@@ -0,0 +1,27 @@
+package com.baeldung.java.regex;
+
+public class Result {
+ private boolean found = false;
+ private int count = 0;
+
+ public Result() {
+
+ }
+
+ public boolean isFound() {
+ return found;
+ }
+
+ public void setFound(boolean found) {
+ this.found = found;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+}
diff --git a/core-java/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java
new file mode 100644
index 0000000000..d4a6a0f42e
--- /dev/null
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java
@@ -0,0 +1,65 @@
+package org.baeldung.equalshashcode.entities;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ComplexClass {
+
+ private List> genericList;
+ private Set integerSet;
+
+ public ComplexClass(ArrayList> genericArrayList, HashSet integerHashSet) {
+ super();
+ this.genericList = genericArrayList;
+ this.integerSet = integerHashSet;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((genericList == null) ? 0 : genericList.hashCode());
+ result = prime * result + ((integerSet == null) ? 0 : integerSet.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ComplexClass))
+ return false;
+ ComplexClass other = (ComplexClass) obj;
+ if (genericList == null) {
+ if (other.genericList != null)
+ return false;
+ } else if (!genericList.equals(other.genericList))
+ return false;
+ if (integerSet == null) {
+ if (other.integerSet != null)
+ return false;
+ } else if (!integerSet.equals(other.integerSet))
+ return false;
+ return true;
+ }
+
+ protected List> getGenericList() {
+ return genericList;
+ }
+
+ protected void setGenericArrayList(List> genericList) {
+ this.genericList = genericList;
+ }
+
+ protected Set getIntegerSet() {
+ return integerSet;
+ }
+
+ protected void setIntegerSet(Set integerSet) {
+ this.integerSet = integerSet;
+ }
+}
diff --git a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java
similarity index 100%
rename from eclipse/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java
rename to core-java/src/main/java/org/baeldung/equalshashcode/entities/PrimitiveClass.java
diff --git a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
similarity index 96%
rename from eclipse/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
rename to core-java/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
index 315ef41a12..1e1423f0b3 100644
--- a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
+++ b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Rectangle.java
@@ -11,13 +11,11 @@ public class Rectangle extends Shape {
@Override
public double area() {
- // A = w * l
return width * length;
}
@Override
public double perimeter() {
- // P = 2(w + l)
return 2 * (width + length);
}
diff --git a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/Shape.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Shape.java
similarity index 100%
rename from eclipse/src/main/java/org/baeldung/equalshashcode/entities/Shape.java
rename to core-java/src/main/java/org/baeldung/equalshashcode/entities/Shape.java
diff --git a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/Square.java b/core-java/src/main/java/org/baeldung/equalshashcode/entities/Square.java
similarity index 100%
rename from eclipse/src/main/java/org/baeldung/equalshashcode/entities/Square.java
rename to core-java/src/main/java/org/baeldung/equalshashcode/entities/Square.java
diff --git a/core-java/src/test/java/com/baeldung/java/regex/RegexTest.java b/core-java/src/test/java/com/baeldung/java/regex/RegexTest.java
new file mode 100644
index 0000000000..257e486600
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/java/regex/RegexTest.java
@@ -0,0 +1,503 @@
+package com.baeldung.java.regex;
+
+import static org.junit.Assert.*;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+public class RegexTest {
+ private static Pattern pattern;
+ private static Matcher matcher;
+
+ @Test
+ public void givenText_whenSimpleRegexMatches_thenCorrect() {
+ Result result = runTest("foo", "foo");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+
+ }
+
+ @Test
+ public void givenText_whenSimpleRegexMatchesTwice_thenCorrect() {
+ Result result = runTest("foo", "foofoo");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+
+ }
+
+ @Test
+ public void givenText_whenMatchesWithDotMetach_thenCorrect() {
+ Result result = runTest(".", "foo");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRepeatedText_whenMatchesOnceWithDotMetach_thenCorrect() {
+ Result result = runTest("foo.", "foofoo");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenORSet_whenMatchesAny_thenCorrect() {
+ Result result = runTest("[abc]", "b");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenORSet_whenMatchesAnyAndAll_thenCorrect() {
+ Result result = runTest("[abc]", "cab");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenORSet_whenMatchesAllCombinations_thenCorrect() {
+ Result result = runTest("[bcr]at", "bat cat rat");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenNORSet_whenMatchesNon_thenCorrect() {
+ Result result = runTest("[^abc]", "g");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenNORSet_whenMatchesAllExceptElements_thenCorrect() {
+ Result result = runTest("[^bcr]at", "sat mat eat");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenUpperCaseRange_whenMatchesUpperCase_thenCorrect() {
+ Result result = runTest("[A-Z]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenLowerCaseRange_whenMatchesLowerCase_thenCorrect() {
+ Result result = runTest("[a-z]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 26);
+ }
+
+ @Test
+ public void givenBothLowerAndUpperCaseRange_whenMatchesAllLetters_thenCorrect() {
+ Result result = runTest("[a-zA-Z]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 28);
+ }
+
+ @Test
+ public void givenNumberRange_whenMatchesAccurately_thenCorrect() {
+ Result result = runTest("[1-5]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenNumberRange_whenMatchesAccurately_thenCorrect2() {
+ Result result = runTest("[30-35]", "Two Uppercase alphabets 34 overall");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenTwoSets_whenMatchesUnion_thenCorrect() {
+ Result result = runTest("[1-3[7-9]]", "123456789");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 6);
+ }
+
+ @Test
+ public void givenTwoSets_whenMatchesIntersection_thenCorrect() {
+ Result result = runTest("[1-6&&[3-9]]", "123456789");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 4);
+ }
+
+ @Test
+ public void givenSetWithSubtraction_whenMatchesAccurately_thenCorrect() {
+ Result result = runTest("[0-9&&[^2468]]", "123456789");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 5);
+ }
+
+ @Test
+ public void givenDigits_whenMatches_thenCorrect() {
+ Result result = runTest("\\d", "123");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenNonDigits_whenMatches_thenCorrect() {
+ Result result = runTest("\\D", "a6c");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenWhiteSpace_whenMatches_thenCorrect() {
+ Result result = runTest("\\s", "a c");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenNonWhiteSpace_whenMatches_thenCorrect() {
+ Result result = runTest("\\S", "a c");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenWordCharacter_whenMatches_thenCorrect() {
+ Result result = runTest("\\w", "hi!");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenNonWordCharacter_whenMatches_thenCorrect() {
+ Result result = runTest("\\W", "hi!");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenZeroOrOneQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("\\a?", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenZeroOrOneQuantifier_whenMatches_thenCorrect2() {
+ Result result = runTest("\\a{0,1}", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenZeroOrManyQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("\\a*", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenZeroOrManyQuantifier_whenMatches_thenCorrect2() {
+ Result result = runTest("\\a{0,}", "hi");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 3);
+ }
+
+ @Test
+ public void givenOneOrManyQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("\\a+", "hi");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenOneOrManyQuantifier_whenMatches_thenCorrect2() {
+ Result result = runTest("\\a{1,}", "hi");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenBraceQuantifier_whenMatches_thenCorrect() {
+ Result result = runTest("a{3}", "aaaaaa");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenBraceQuantifier_whenFailsToMatch_thenCorrect() {
+ Result result = runTest("a{3}", "aa");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenBraceQuantifierWithRange_whenMatches_thenCorrect() {
+ Result result = runTest("a{2,3}", "aaaa");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenBraceQuantifierWithRange_whenMatchesLazily_thenCorrect() {
+ Result result = runTest("a{2,3}?", "aaaa");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatches_thenCorrect() {
+ Result result = runTest("(\\d\\d)", "12");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatches_thenCorrect2() {
+ Result result = runTest("(\\d\\d)", "1212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 2);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatches_thenCorrect3() {
+ Result result = runTest("(\\d\\d)(\\d\\d)", "1212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatchesWithBackReference_thenCorrect() {
+ Result result = runTest("(\\d\\d)\\1", "1212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroup_whenMatchesWithBackReference_thenCorrect2() {
+ Result result = runTest("(\\d\\d)\\1\\1\\1", "12121212");
+ assertTrue(result.isFound());
+ assertEquals(result.getCount(), 1);
+ }
+
+ @Test
+ public void givenCapturingGroupAndWrongInput_whenMatchFailsWithBackReference_thenCorrect() {
+ Result result = runTest("(\\d\\d)\\1", "1213");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtBeginning_thenCorrect() {
+ Result result = runTest("^dog", "dogs are friendly");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenTextAndWrongInput_whenMatchFailsAtBeginning_thenCorrect() {
+ Result result = runTest("^dog", "are dogs are friendly?");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtEnd_thenCorrect() {
+ Result result = runTest("dog$", "Man's best friend is a dog");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenTextAndWrongInput_whenMatchFailsAtEnd_thenCorrect() {
+ Result result = runTest("dog$", "is a dog man's best friend?");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtWordBoundary_thenCorrect() {
+ Result result = runTest("\\bdog\\b", "a dog is friendly");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtWordBoundary_thenCorrect2() {
+ Result result = runTest("\\bdog\\b", "dog is man's best friend");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenWrongText_whenMatchFailsAtWordBoundary_thenCorrect() {
+ Result result = runTest("\\bdog\\b", "snoop dogg is a rapper");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenText_whenMatchesAtWordAndNonBoundary_thenCorrect() {
+ Result result = runTest("\\bdog\\B", "snoop dogg is a rapper");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithoutCanonEq_whenMatchFailsOnEquivalentUnicode_thenCorrect() {
+ Result result = runTest("\u00E9", "\u0065\u0301");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithCanonEq_whenMatchesOnEquivalentUnicode_thenCorrect() {
+ Result result = runTest("\u00E9", "\u0065\u0301", Pattern.CANON_EQ);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithDefaultMatcher_whenMatchFailsOnDifferentCases_thenCorrect() {
+ Result result = runTest("dog", "This is a Dog");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithCaseInsensitiveMatcher_whenMatchesOnDifferentCases_thenCorrect() {
+ Result result = runTest("dog", "This is a Dog", Pattern.CASE_INSENSITIVE);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithEmbeddedCaseInsensitiveMatcher_whenMatchesOnDifferentCases_thenCorrect() {
+ Result result = runTest("(?i)dog", "This is a Dog");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithComments_whenMatchFailsWithoutFlag_thenCorrect() {
+ Result result = runTest("dog$ #check for word dog at end of text", "This is a dog");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithComments_whenMatchesWithFlag_thenCorrect() {
+ Result result = runTest("dog$ #check for word dog at end of text", "This is a dog", Pattern.COMMENTS);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithComments_whenMatchesWithEmbeddedFlag_thenCorrect() {
+ Result result = runTest("(?x)dog$ #check for word dog at end of text", "This is a dog");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegexWithLineTerminator_whenMatchFails_thenCorrect() {
+ Pattern pattern = Pattern.compile("(.*)");
+ Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line");
+ matcher.find();
+ assertEquals("this is a text", matcher.group(1));
+ }
+
+ @Test
+ public void givenRegexWithLineTerminator_whenMatchesWithDotall_thenCorrect() {
+ Pattern pattern = Pattern.compile("(.*)", Pattern.DOTALL);
+ Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line");
+ matcher.find();
+ assertEquals("this is a text" + System.getProperty("line.separator") + " continued on another line", matcher.group(1));
+ }
+
+ @Test
+ public void givenRegexWithLineTerminator_whenMatchesWithEmbeddedDotall_thenCorrect() {
+ Pattern pattern = Pattern.compile("(?s)(.*)");
+ Matcher matcher = pattern.matcher("this is a text" + System.getProperty("line.separator") + " continued on another line");
+ matcher.find();
+ assertEquals("this is a text" + System.getProperty("line.separator") + " continued on another line", matcher.group(1));
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithoutLiteralFlag_thenCorrect() {
+ Result result = runTest("(.*)", "text");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchFailsWithLiteralFlag_thenCorrect() {
+ Result result = runTest("(.*)", "text", Pattern.LITERAL);
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithLiteralFlag_thenCorrect() {
+ Result result = runTest("(.*)", "text(.*)", Pattern.LITERAL);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchFailsWithoutMultilineFlag_thenCorrect() {
+ Result result = runTest("dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox");
+ assertFalse(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithMultilineFlag_thenCorrect() {
+ Result result = runTest("dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox", Pattern.MULTILINE);
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenRegex_whenMatchesWithEmbeddedMultilineFlag_thenCorrect() {
+ Result result = runTest("(?m)dog$", "This is a dog" + System.getProperty("line.separator") + "this is a fox");
+ assertTrue(result.isFound());
+ }
+
+ @Test
+ public void givenMatch_whenGetsIndices_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("This dog is mine");
+ matcher.find();
+ assertEquals(5, matcher.start());
+ assertEquals(8, matcher.end());
+ }
+
+ @Test
+ public void whenStudyMethodsWork_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dogs are friendly");
+ assertTrue(matcher.lookingAt());
+ assertFalse(matcher.matches());
+
+ }
+
+ @Test
+ public void whenMatchesStudyMethodWorks_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dog");
+ assertTrue(matcher.matches());
+
+ }
+
+ @Test
+ public void whenReplaceFirstWorks_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dogs are domestic animals, dogs are friendly");
+ String newStr = matcher.replaceFirst("cat");
+ assertEquals("cats are domestic animals, dogs are friendly", newStr);
+
+ }
+
+ @Test
+ public void whenReplaceAllWorks_thenCorrect() {
+ Pattern pattern = Pattern.compile("dog");
+ Matcher matcher = pattern.matcher("dogs are domestic animals, dogs are friendly");
+ String newStr = matcher.replaceAll("cat");
+ assertEquals("cats are domestic animals, cats are friendly", newStr);
+
+ }
+
+ public synchronized static Result runTest(String regex, String text) {
+ pattern = Pattern.compile(regex);
+ matcher = pattern.matcher(text);
+ Result result = new Result();
+ while (matcher.find())
+ result.setCount(result.getCount() + 1);
+ if (result.getCount() > 0)
+ result.setFound(true);
+ return result;
+ }
+
+ public synchronized static Result runTest(String regex, String text, int flags) {
+ pattern = Pattern.compile(regex, flags);
+ matcher = pattern.matcher(text);
+ Result result = new Result();
+ while (matcher.find())
+ result.setCount(result.getCount() + 1);
+ if (result.getCount() > 0)
+ result.setFound(true);
+ return result;
+ }
+}
diff --git a/eclipse/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
similarity index 90%
rename from eclipse/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
rename to core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
index 09123e988b..75d96e5989 100644
--- a/eclipse/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
+++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/ComplexClassTest.java
@@ -22,11 +22,10 @@ public class ComplexClassTest {
strArrayListD.add("pqr");
ComplexClass dObject = new ComplexClass(strArrayListD, new HashSet(45, 67));
- // equals()
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
- // hashCode()
+
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
- // non-equal objects are not equals() and have different hashCode()
+
Assert.assertFalse(aObject.equals(dObject));
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
}
diff --git a/eclipse/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
similarity index 84%
rename from eclipse/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
rename to core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
index feb04d65ff..16f25ae021 100644
--- a/eclipse/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
+++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/PrimitiveClassTest.java
@@ -12,11 +12,10 @@ public class PrimitiveClassTest {
PrimitiveClass bObject = new PrimitiveClass(false, 2);
PrimitiveClass dObject = new PrimitiveClass(true, 2);
- // equals()
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
- // hashCode()
+
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
- // non-equal objects are not equals() and have different hashCode()
+
Assert.assertFalse(aObject.equals(dObject));
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
}
diff --git a/eclipse/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java b/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
similarity index 84%
rename from eclipse/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
rename to core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
index 53ca199405..52d024a696 100644
--- a/eclipse/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
+++ b/core-java/src/test/java/org/baeldung/equalshashcode/entities/SquareClassTest.java
@@ -15,11 +15,10 @@ public class SquareClassTest {
Square dObject = new Square(20, Color.BLUE);
- // equals()
Assert.assertTrue(aObject.equals(bObject) && bObject.equals(aObject));
- // hashCode()
+
Assert.assertTrue(aObject.hashCode() == bObject.hashCode());
- // non-equal objects are not equals() and have different hashCode()
+
Assert.assertFalse(aObject.equals(dObject));
Assert.assertFalse(aObject.hashCode() == dObject.hashCode());
}
diff --git a/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java
new file mode 100644
index 0000000000..83f1fb33b6
--- /dev/null
+++ b/core-java/src/test/java/org/baeldung/java/md5/JavaMD5Test.java
@@ -0,0 +1,90 @@
+package org.baeldung.java.md5;
+
+import static org.junit.Assert.*;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class JavaMD5Test {
+
+
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+
+
+ @Test
+ public void givenPassword_whenHashing_thenVerifying() throws NoSuchAlgorithmException {
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(password.getBytes());
+ byte[] digest = md.digest();
+ String myHash = DatatypeConverter.printHexBinary(digest).toUpperCase();
+
+ assertThat(myHash.equals(hash)).isTrue();
+ }
+
+ @Test
+ public void givenFile_generatingChecksum_thenVerifying() throws NoSuchAlgorithmException, IOException {
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(Files.readAllBytes(Paths.get(filename)));
+ byte[] digest = md.digest();
+ String myChecksum = DatatypeConverter
+ .printHexBinary(digest).toUpperCase();
+
+ assertThat(myChecksum.equals(checksum)).isTrue();
+ }
+
+ @Test
+ public void givenPassword_whenHashingUsingCommons_thenVerifying() {
+ String hash = "35454B055CC325EA1AF2126E27707052";
+ String password = "ILoveJava";
+
+ String md5Hex = DigestUtils
+ .md5Hex(password).toUpperCase();
+
+ assertThat(md5Hex.equals(hash)).isTrue();
+ }
+
+
+ @Test
+ public void givenFile_whenChecksumUsingGuava_thenVerifying() throws IOException {
+ String filename = "src/test/resources/test_md5.txt";
+ String checksum = "5EB63BBBE01EEED093CB22BB8F5ACDC3";
+
+ HashCode hash = com.google.common.io.Files
+ .hash(new File(filename), Hashing.md5());
+ String myChecksum = hash.toString()
+ .toUpperCase();
+
+ assertThat(myChecksum.equals(checksum)).isTrue();
+ }
+
+
+}
diff --git a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java b/eclipse/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java
deleted file mode 100644
index 3f7723facd..0000000000
--- a/eclipse/src/main/java/org/baeldung/equalshashcode/entities/ComplexClass.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.baeldung.equalshashcode.entities;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-
-public class ComplexClass {
-
- private ArrayList> genericArrayList;
- private HashSet integerHashSet;
-
- public ComplexClass(ArrayList> genericArrayList, HashSet integerHashSet) {
- super();
- this.genericArrayList = genericArrayList;
- this.integerHashSet = integerHashSet;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((genericArrayList == null) ? 0 : genericArrayList.hashCode());
- result = prime * result + ((integerHashSet == null) ? 0 : integerHashSet.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (!(obj instanceof ComplexClass))
- return false;
- ComplexClass other = (ComplexClass) obj;
- if (genericArrayList == null) {
- if (other.genericArrayList != null)
- return false;
- } else if (!genericArrayList.equals(other.genericArrayList))
- return false;
- if (integerHashSet == null) {
- if (other.integerHashSet != null)
- return false;
- } else if (!integerHashSet.equals(other.integerHashSet))
- return false;
- return true;
- }
-
- protected ArrayList> getGenericArrayList() {
- return genericArrayList;
- }
-
- protected void setGenericArrayList(ArrayList> genericArrayList) {
- this.genericArrayList = genericArrayList;
- }
-
- protected HashSet getIntegerHashSet() {
- return integerHashSet;
- }
-
- protected void setIntegerHashSet(HashSet integerHashSet) {
- this.integerHashSet = integerHashSet;
- }
-}
diff --git a/enterprise-patterns/front-controller-pattern/src/main/resources/front controller.png b/enterprise-patterns/front-controller-pattern/src/main/resources/front controller.png
deleted file mode 100644
index bd475bf3f3..0000000000
Binary files a/enterprise-patterns/front-controller-pattern/src/main/resources/front controller.png and /dev/null differ
diff --git a/enterprise-patterns/pom.xml b/enterprise-patterns/pom.xml
deleted file mode 100644
index 2fba12547f..0000000000
--- a/enterprise-patterns/pom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- 4.0.0
-
- com.baeldung.enterprise.patterns
- enterprise-patterns-parent
- pom
-
- front-controller-pattern
-
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.5.1
-
- 1.8
- 1.8
-
-
-
-
-
-
diff --git a/enterprise-patterns/front-controller-pattern/pom.xml b/patterns/pom.xml
similarity index 77%
rename from enterprise-patterns/front-controller-pattern/pom.xml
rename to patterns/pom.xml
index dbcd4f1b1d..7c23b6f55d 100644
--- a/enterprise-patterns/front-controller-pattern/pom.xml
+++ b/patterns/pom.xml
@@ -4,15 +4,10 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- front-controller-pattern
+ com.baeldung.enterprise.patterns
+ patterns
war
-
- enterprise-patterns-parent
- com.baeldung.enterprise.patterns
- 1.0.0-SNAPSHOT
-
-
javax.servlet
@@ -22,11 +17,22 @@
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
org.apache.maven.plugins
maven-compiler-plugin
+ 3.5.1
+
+ 1.8
+ 1.8
+
org.eclipse.jetty
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/FrontControllerServlet.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/FrontControllerServlet.java
similarity index 77%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/FrontControllerServlet.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/FrontControllerServlet.java
index 4dfc12c050..a8962f5108 100644
--- a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/FrontControllerServlet.java
+++ b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/FrontControllerServlet.java
@@ -22,24 +22,17 @@ public class FrontControllerServlet extends HttpServlet {
private FrontCommand getCommand(HttpServletRequest request) {
try {
- return (FrontCommand) getCommandClass(request)
- .asSubclass(FrontCommand.class)
- .newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Failed to get command!", e);
- }
- }
-
- private Class getCommandClass(HttpServletRequest request) {
- try {
- return Class.forName(
+ Class type = Class.forName(
String.format(
"com.baeldung.enterprise.patterns.front.controller.commands.%sCommand",
request.getParameter("command")
)
);
- } catch (ClassNotFoundException e) {
- return UnknownCommand.class;
+ return (FrontCommand) type
+ .asSubclass(FrontCommand.class)
+ .newInstance();
+ } catch (Exception e) {
+ return new UnknownCommand();
}
}
}
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/FrontCommand.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/FrontCommand.java
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/FrontCommand.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/FrontCommand.java
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/SearchCommand.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/SearchCommand.java
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/SearchCommand.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/SearchCommand.java
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/UnknownCommand.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/UnknownCommand.java
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/UnknownCommand.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/commands/UnknownCommand.java
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Book.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Book.java
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Book.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Book.java
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Bookshelf.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Bookshelf.java
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Bookshelf.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/Bookshelf.java
diff --git a/enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/BookshelfImpl.java b/patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/BookshelfImpl.java
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/BookshelfImpl.java
rename to patterns/src/main/java/com/baeldung/enterprise/patterns/front/controller/data/BookshelfImpl.java
diff --git a/patterns/src/main/resources/front controller.png b/patterns/src/main/resources/front controller.png
new file mode 100644
index 0000000000..af22a38e37
Binary files /dev/null and b/patterns/src/main/resources/front controller.png differ
diff --git a/enterprise-patterns/front-controller-pattern/src/main/resources/front controller.puml b/patterns/src/main/resources/front controller.puml
similarity index 93%
rename from enterprise-patterns/front-controller-pattern/src/main/resources/front controller.puml
rename to patterns/src/main/resources/front controller.puml
index fbd4f416ef..cbc2dc8bd9 100644
--- a/enterprise-patterns/front-controller-pattern/src/main/resources/front controller.puml
+++ b/patterns/src/main/resources/front controller.puml
@@ -1,5 +1,5 @@
@startuml
-
+scale 1.5
class Handler {
doGet
doPost
diff --git a/enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/jsp/book-found.jsp b/patterns/src/main/webapp/WEB-INF/jsp/book-found.jsp
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/jsp/book-found.jsp
rename to patterns/src/main/webapp/WEB-INF/jsp/book-found.jsp
diff --git a/enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/jsp/book-notfound.jsp b/patterns/src/main/webapp/WEB-INF/jsp/book-notfound.jsp
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/jsp/book-notfound.jsp
rename to patterns/src/main/webapp/WEB-INF/jsp/book-notfound.jsp
diff --git a/enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/jsp/unknown.jsp b/patterns/src/main/webapp/WEB-INF/jsp/unknown.jsp
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/jsp/unknown.jsp
rename to patterns/src/main/webapp/WEB-INF/jsp/unknown.jsp
diff --git a/enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/web.xml b/patterns/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from enterprise-patterns/front-controller-pattern/src/main/webapp/WEB-INF/web.xml
rename to patterns/src/main/webapp/WEB-INF/web.xml
diff --git a/pom.xml b/pom.xml
index 8115c1e902..b4158ef67e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
dependency-injection
deltaspike
- enterprise-patterns
+ patterns
feign-client
@@ -91,12 +91,12 @@
spring-hibernate3
spring-hibernate4
spring-jpa
- spring-jpa-jndi
spring-katharsis
spring-mockito
spring-mvc-java
spring-mvc-no-xml
spring-mvc-xml
+ spring-mvc-tiles
spring-openid
spring-protobuf
spring-quartz
@@ -133,6 +133,7 @@
wicket
xstream
java-cassandra
+ annotations
diff --git a/spring-cloud/README.md b/spring-cloud/README.md
index 86f67cf26e..3e8cd21b82 100644
--- a/spring-cloud/README.md
+++ b/spring-cloud/README.md
@@ -1,8 +1,18 @@
## The Module Holds Sources for the Following Articles
- [Quick Intro to Spring Cloud Configuration](http://www.baeldung.com/spring-cloud-configuration)
-- [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application)
+
+ Spring Cloud Config is Spring’s client/server approach for storing and serving distributed configurations across multiple applications and environments.
+
+ In this write-up, we’ll focus on an example of how to setup a Git-backed config server, use it in a simple REST application server and setup a secure environment including encrypted property values.
+
- [Introduction to Spring Cloud Netflix – Eureka](http://www.baeldung.com/spring-cloud-netflix-eureka)
+
+ In this article, we’ll introduce client-side service discovery via “Spring Cloud Netflix Eureka“.
+
+ Client-side service discovery allows services to find and communicate with each other without hardcoding hostname and port. The only ‘fixed point’ in such an architecture consists of a service registry with which each service has to register.
+
- [Intro to Spring Cloud Netflix - Hystrix](http://www.baeldung.com/spring-cloud-netflix-hystrix)
+- [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application)
diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml
index 340923cbdf..2349613def 100644
--- a/spring-cloud/pom.xml
+++ b/spring-cloud/pom.xml
@@ -10,7 +10,7 @@
spring-cloud-config
spring-cloud-eureka
spring-cloud-hystrix
- spring-cloud-integration
+ spring-cloud-bootstrap
pom
diff --git a/spring-cloud/spring-cloud-integration/part-1/application-config/discovery.properties b/spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/application-config/discovery.properties
rename to spring-cloud/spring-cloud-bootstrap/application-config/discovery.properties
diff --git a/spring-cloud/spring-cloud-integration/part-1/application-config/gateway.properties b/spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/application-config/gateway.properties
rename to spring-cloud/spring-cloud-bootstrap/application-config/gateway.properties
diff --git a/spring-cloud/spring-cloud-integration/part-1/application-config/resource.properties b/spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/application-config/resource.properties
rename to spring-cloud/spring-cloud-bootstrap/application-config/resource.properties
diff --git a/spring-cloud/spring-cloud-integration/part-1/config/pom.xml b/spring-cloud/spring-cloud-bootstrap/config/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/config/pom.xml
rename to spring-cloud/spring-cloud-bootstrap/config/pom.xml
diff --git a/spring-cloud/spring-cloud-integration/part-1/config/src/main/java/com/baeldung/spring/cloud/integration/config/ConfigApplication.java b/spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/integration/config/ConfigApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/config/src/main/java/com/baeldung/spring/cloud/integration/config/ConfigApplication.java
rename to spring-cloud/spring-cloud-bootstrap/config/src/main/java/com/baeldung/spring/cloud/integration/config/ConfigApplication.java
diff --git a/spring-cloud/spring-cloud-integration/part-1/config/src/main/resources/application.properties b/spring-cloud/spring-cloud-bootstrap/config/src/main/resources/application.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/config/src/main/resources/application.properties
rename to spring-cloud/spring-cloud-bootstrap/config/src/main/resources/application.properties
diff --git a/spring-cloud/spring-cloud-integration/part-1/discovery/pom.xml b/spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/discovery/pom.xml
rename to spring-cloud/spring-cloud-bootstrap/discovery/pom.xml
diff --git a/spring-cloud/spring-cloud-integration/part-1/discovery/src/main/java/com/baeldung/spring/cloud/integration/discovery/DiscoveryApplication.java b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/integration/discovery/DiscoveryApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/discovery/src/main/java/com/baeldung/spring/cloud/integration/discovery/DiscoveryApplication.java
rename to spring-cloud/spring-cloud-bootstrap/discovery/src/main/java/com/baeldung/spring/cloud/integration/discovery/DiscoveryApplication.java
diff --git a/spring-cloud/spring-cloud-integration/part-1/discovery/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/bootstrap.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/discovery/src/main/resources/bootstrap.properties
rename to spring-cloud/spring-cloud-bootstrap/discovery/src/main/resources/bootstrap.properties
diff --git a/spring-cloud/spring-cloud-integration/part-1/gateway/pom.xml b/spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/gateway/pom.xml
rename to spring-cloud/spring-cloud-bootstrap/gateway/pom.xml
diff --git a/spring-cloud/spring-cloud-integration/part-1/gateway/src/main/java/com/baeldung/spring/cloud/integration/resource/GatewayApplication.java b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/integration/resource/GatewayApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/gateway/src/main/java/com/baeldung/spring/cloud/integration/resource/GatewayApplication.java
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/java/com/baeldung/spring/cloud/integration/resource/GatewayApplication.java
diff --git a/spring-cloud/spring-cloud-integration/part-1/gateway/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/gateway/src/main/resources/bootstrap.properties
rename to spring-cloud/spring-cloud-bootstrap/gateway/src/main/resources/bootstrap.properties
diff --git a/spring-cloud/spring-cloud-integration/part-1/pom.xml b/spring-cloud/spring-cloud-bootstrap/pom.xml
similarity index 85%
rename from spring-cloud/spring-cloud-integration/part-1/pom.xml
rename to spring-cloud/spring-cloud-bootstrap/pom.xml
index 770e26bca2..c14c277d7f 100644
--- a/spring-cloud/spring-cloud-integration/part-1/pom.xml
+++ b/spring-cloud/spring-cloud-bootstrap/pom.xml
@@ -6,7 +6,7 @@
com.baeldung.spring.cloud
- spring-cloud-integration
+ spring-cloud
1.0.0-SNAPSHOT
@@ -17,9 +17,9 @@
resource
- part-1
+
+ spring-cloud-integration
1.0.0-SNAPSHOT
pom
-
\ No newline at end of file
diff --git a/spring-cloud/spring-cloud-integration/part-1/resource/pom.xml b/spring-cloud/spring-cloud-bootstrap/resource/pom.xml
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/resource/pom.xml
rename to spring-cloud/spring-cloud-bootstrap/resource/pom.xml
diff --git a/spring-cloud/spring-cloud-integration/part-1/resource/src/main/java/com/baeldung/spring/cloud/integration/resource/ResourceApplication.java b/spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/integration/resource/ResourceApplication.java
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/resource/src/main/java/com/baeldung/spring/cloud/integration/resource/ResourceApplication.java
rename to spring-cloud/spring-cloud-bootstrap/resource/src/main/java/com/baeldung/spring/cloud/integration/resource/ResourceApplication.java
diff --git a/spring-cloud/spring-cloud-integration/part-1/resource/src/main/resources/bootstrap.properties b/spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
similarity index 100%
rename from spring-cloud/spring-cloud-integration/part-1/resource/src/main/resources/bootstrap.properties
rename to spring-cloud/spring-cloud-bootstrap/resource/src/main/resources/bootstrap.properties
diff --git a/spring-data-neo4j/README.md b/spring-data-neo4j/README.md
index e62c69f8b9..0f13d9dbc9 100644
--- a/spring-data-neo4j/README.md
+++ b/spring-data-neo4j/README.md
@@ -1,7 +1,7 @@
## Spring Data Neo4j
### Relevant Articles:
-- [Introduction to Spring Data Neo4j](http://www.baeldung.com/spring-data-neo4j-tutorial)
+- [Introduction to Spring Data Neo4j](http://www.baeldung.com/spring-data-neo4j-intro)
### Build the Project with Tests Running
```
diff --git a/spring-jpa-jndi/.gitignore b/spring-jpa-jndi/.gitignore
deleted file mode 100644
index 83c05e60c8..0000000000
--- a/spring-jpa-jndi/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-*.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/spring-jpa-jndi/README.md b/spring-jpa-jndi/README.md
deleted file mode 100644
index 6a99253545..0000000000
--- a/spring-jpa-jndi/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-=========
-
-## Spring JPA using JNDI Project
-
-
-### Relevant Articles:
-- [Spring Persistence (Hibernate and JPA) with a JNDI datasource](http://www.baeldung.com/spring-jpa-fndi)
\ No newline at end of file
diff --git a/spring-jpa-jndi/pom.xml b/spring-jpa-jndi/pom.xml
deleted file mode 100644
index f7042f2384..0000000000
--- a/spring-jpa-jndi/pom.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-
- 4.0.0
-
- com.baeldung
- spring-jpa-jndi
- 0.1-SNAPSHOT
- war
-
- spring-jpa-jndi
-
-
-
-
-
-
- org.springframework
- spring-orm
- ${org.springframework.version}
-
-
- org.springframework
- spring-context
- ${org.springframework.version}
-
-
- org.springframework
- spring-webmvc
- ${org.springframework.version}
-
-
-
-
- javax.servlet
- jstl
- ${javax.servlet.jstl.version}
-
-
- javax.servlet
- servlet-api
- ${javax.servlet.servlet-api.version}
-
-
-
-
-
- org.hibernate
- hibernate-entitymanager
- ${hibernate.version}
-
-
- xml-apis
- xml-apis
- 1.4.01
-
-
- org.javassist
- javassist
- ${javassist.version}
-
-
- org.springframework.data
- spring-data-jpa
- ${spring-data-jpa.version}
-
-
-
-
-
- org.hibernate
- hibernate-validator
- ${hibernate-validator.version}
-
-
- javax.el
- javax.el-api
- 2.2.5
-
-
-
-
-
- spring-jpa-jndi
-
-
- src/main/resources
- true
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- 1.8
- 1.8
-
-
-
-
- org.apache.maven.plugins
- maven-war-plugin
- ${maven-war-plugin.version}
-
- src/main/webapp
- false
-
-
-
-
-
-
-
-
-
- 4.3.2.RELEASE
- 3.20.0-GA
-
-
- 1.2
- 2.5
-
-
- 4.3.11.Final
- 1.8.2.RELEASE
- 1.4.192
-
-
- 1.7.13
- 1.1.3
-
-
- 5.2.2.Final
-
-
- 3.5.1
- 2.7
- 2.4
-
-
-
-
-
\ No newline at end of file
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/persistence/dao/FooDao.java b/spring-jpa-jndi/src/main/java/org/baeldung/persistence/dao/FooDao.java
deleted file mode 100644
index 0133a36a14..0000000000
--- a/spring-jpa-jndi/src/main/java/org/baeldung/persistence/dao/FooDao.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.baeldung.persistence.dao;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import org.baeldung.persistence.model.Foo;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public class FooDao {
-
- @PersistenceContext
- private EntityManager entityManager;
-
- @SuppressWarnings("unchecked")
- public List findAll() {
- return entityManager.createQuery("from " + Foo.class.getName()).getResultList();
- }
-
-}
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/persistence/model/Foo.java b/spring-jpa-jndi/src/main/java/org/baeldung/persistence/model/Foo.java
deleted file mode 100644
index d351fc54b8..0000000000
--- a/spring-jpa-jndi/src/main/java/org/baeldung/persistence/model/Foo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.baeldung.persistence.model;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-@Entity
-public class Foo {
-
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- @Column(name = "ID")
- private long id;
- @Column(name = "NAME")
- private String name;
-
- public long getId() {
- return id;
- }
-
- public void setId(final int id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(final String name) {
- this.name = name;
- }
-}
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/persistence/service/FooService.java b/spring-jpa-jndi/src/main/java/org/baeldung/persistence/service/FooService.java
deleted file mode 100644
index a3109f5042..0000000000
--- a/spring-jpa-jndi/src/main/java/org/baeldung/persistence/service/FooService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.baeldung.persistence.service;
-
-import java.util.List;
-
-import org.baeldung.persistence.dao.FooDao;
-import org.baeldung.persistence.model.Foo;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-@Service
-@Transactional
-public class FooService {
-
- @Autowired
- private FooDao dao;
-
- public List findAll() {
- return dao.findAll();
- }
-
-}
diff --git a/spring-jpa-jndi/src/main/resources/logback.xml b/spring-jpa-jndi/src/main/resources/logback.xml
deleted file mode 100644
index 1146dade63..0000000000
--- a/spring-jpa-jndi/src/main/resources/logback.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- web - %date [%thread] %-5level %logger{36} - %message%n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/spring-jpa/pom.xml b/spring-jpa/pom.xml
index 5acdae7765..ebb9c5bc83 100644
--- a/spring-jpa/pom.xml
+++ b/spring-jpa/pom.xml
@@ -4,6 +4,7 @@
com.baeldung
spring-jpa
0.1-SNAPSHOT
+ war
spring-jpa
@@ -21,6 +22,11 @@
spring-context
${org.springframework.version}
+
+ org.springframework
+ spring-webmvc
+ ${org.springframework.version}
+
@@ -73,6 +79,18 @@
javax.el-api
2.2.5
+
+
+
+ javax.servlet
+ jstl
+ ${javax.servlet.jstl.version}
+
+
+ javax.servlet
+ servlet-api
+ ${javax.servlet.servlet-api.version}
+
@@ -147,6 +165,16 @@
1.8
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ src/main/webapp
+ false
+
+
org.apache.maven.plugins
@@ -197,6 +225,10 @@
5.1.38
1.10.2.RELEASE
1.4.192
+
+
+ 1.2
+ 2.5
1.7.13
@@ -224,6 +256,7 @@
2.19.1
2.7
1.4.18
+ 2.4
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java b/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java
similarity index 90%
rename from spring-jpa-jndi/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java
rename to spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java
index 7ea731d9d4..7f28c958f1 100644
--- a/spring-jpa-jndi/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java
+++ b/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java
@@ -36,7 +36,7 @@ public class PersistenceJNDIConfig {
}
@Bean
- public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
@@ -46,12 +46,8 @@ public class PersistenceJNDIConfig {
}
@Bean
- public DataSource dataSource() {
- try {
- return (DataSource) new JndiTemplate().lookup(env.getProperty("jdbc.url"));
- } catch (NamingException e) {
- throw new IllegalArgumentException("Error looking up JNDI datasource", e);
- }
+ public DataSource dataSource() throws NamingException {
+ return (DataSource) new JndiTemplate().lookup(env.getProperty("jdbc.url"));
}
@Bean
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/config/SpringWebConfig.java b/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java
similarity index 100%
rename from spring-jpa-jndi/src/main/java/org/baeldung/config/SpringWebConfig.java
rename to spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/config/WebInitializer.java b/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java
similarity index 100%
rename from spring-jpa-jndi/src/main/java/org/baeldung/config/WebInitializer.java
rename to spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java
diff --git a/spring-jpa-jndi/src/main/java/org/baeldung/web/MainController.java b/spring-jpa/src/main/java/org/baeldung/web/MainController.java
similarity index 100%
rename from spring-jpa-jndi/src/main/java/org/baeldung/web/MainController.java
rename to spring-jpa/src/main/java/org/baeldung/web/MainController.java
diff --git a/spring-jpa-jndi/src/main/resources/context.xml b/spring-jpa/src/main/resources/context.xml
similarity index 100%
rename from spring-jpa-jndi/src/main/resources/context.xml
rename to spring-jpa/src/main/resources/context.xml
diff --git a/spring-jpa-jndi/src/main/resources/persistence-jndi.properties b/spring-jpa/src/main/resources/persistence-jndi.properties
similarity index 100%
rename from spring-jpa-jndi/src/main/resources/persistence-jndi.properties
rename to spring-jpa/src/main/resources/persistence-jndi.properties
diff --git a/spring-jpa-jndi/src/main/resources/server.xml b/spring-jpa/src/main/resources/server.xml
similarity index 100%
rename from spring-jpa-jndi/src/main/resources/server.xml
rename to spring-jpa/src/main/resources/server.xml
diff --git a/spring-jpa-jndi/src/main/webapp/WEB-INF/views/jsp/index.jsp b/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp
similarity index 100%
rename from spring-jpa-jndi/src/main/webapp/WEB-INF/views/jsp/index.jsp
rename to spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp
diff --git a/spring-mvc-tiles/pom.xml b/spring-mvc-tiles/pom.xml
new file mode 100644
index 0000000000..1a72549e70
--- /dev/null
+++ b/spring-mvc-tiles/pom.xml
@@ -0,0 +1,85 @@
+
+ 4.0.0
+ com.baeldung
+ spring-mvc-tiles
+ 0.0.1-SNAPSHOT
+ war
+ spring-mvc-tiles
+ Integrating Spring MVC with Apache Tiles
+
+
+ 4.3.2.RELEASE
+ 3.0.5
+
+
+
+
+
+ org.springframework
+ spring-core
+ ${springframework.version}
+
+
+ org.springframework
+ spring-web
+ ${springframework.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${springframework.version}
+
+
+
+ org.apache.tiles
+ tiles-jsp
+ ${apachetiles.version}
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+
+
+ javax.servlet.jsp
+ javax.servlet.jsp-api
+ 2.3.1
+
+
+ javax.servlet
+ jstl
+ 1.2
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.2
+
+ 1.7
+ 1.7
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 2.4
+
+ src/main/webapp
+ spring-mvc-tiles
+ false
+
+
+
+
+ spring-mvc-tiles
+
+
diff --git a/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationConfiguration.java b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationConfiguration.java
new file mode 100644
index 0000000000..d2e90a4f53
--- /dev/null
+++ b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationConfiguration.java
@@ -0,0 +1,47 @@
+package com.baeldung.tiles.springmvc;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
+import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan(basePackages = "com.baeldung.tiles.springmvc")
+public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
+
+ /**
+ * Configure TilesConfigurer.
+ */
+ @Bean
+ public TilesConfigurer tilesConfigurer() {
+ TilesConfigurer tilesConfigurer = new TilesConfigurer();
+ tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/views/**/tiles.xml" });
+ tilesConfigurer.setCheckRefresh(true);
+ return tilesConfigurer;
+ }
+
+ /**
+ * Configure ViewResolvers to deliver views.
+ */
+ @Override
+ public void configureViewResolvers(ViewResolverRegistry registry) {
+ TilesViewResolver viewResolver = new TilesViewResolver();
+ registry.viewResolver(viewResolver);
+ }
+
+ /**
+ * Configure ResourceHandlers to serve static resources
+ */
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/static/**").addResourceLocations("/static/");
+ }
+
+}
diff --git a/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationController.java b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationController.java
new file mode 100644
index 0000000000..1a348d1c26
--- /dev/null
+++ b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationController.java
@@ -0,0 +1,26 @@
+package com.baeldung.tiles.springmvc;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+@RequestMapping("/")
+public class ApplicationController {
+
+ @RequestMapping(value = { "/" }, method = RequestMethod.GET)
+ public String homePage(ModelMap model) {
+ return "home";
+ }
+
+ @RequestMapping(value = { "/apachetiles" }, method = RequestMethod.GET)
+ public String productsPage(ModelMap model) {
+ return "apachetiles";
+ }
+
+ @RequestMapping(value = { "/springmvc" }, method = RequestMethod.GET)
+ public String contactUsPage(ModelMap model) {
+ return "springmvc";
+ }
+}
diff --git a/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationInitializer.java b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationInitializer.java
new file mode 100644
index 0000000000..79583dbe83
--- /dev/null
+++ b/spring-mvc-tiles/src/main/java/com/baeldung/tiles/springmvc/ApplicationInitializer.java
@@ -0,0 +1,22 @@
+package com.baeldung.tiles.springmvc;
+
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return new Class[] { ApplicationConfiguration.class };
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return null;
+ }
+
+ @Override
+ protected String[] getServletMappings() {
+ return new String[] { "/" };
+ }
+
+}
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/apachetiles.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/apachetiles.jsp
new file mode 100644
index 0000000000..9936957c04
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/apachetiles.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Apache Tiles
+
+
+Tiles with Spring MVC Demo
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/home.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/home.jsp
new file mode 100644
index 0000000000..b501d4968e
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/home.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Home
+
+
+Welcome to Apache Tiles integration with Spring MVC
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/springmvc.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/springmvc.jsp
new file mode 100644
index 0000000000..209b1004de
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/pages/springmvc.jsp
@@ -0,0 +1,12 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+
+
+
+Spring MVC
+
+
+Spring MVC configured to work with Apache Tiles
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/layouts/defaultLayout.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/layouts/defaultLayout.jsp
new file mode 100644
index 0000000000..2370ad4ab1
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/layouts/defaultLayout.jsp
@@ -0,0 +1,25 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+<%@ page isELIgnored="false"%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultFooter.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultFooter.jsp
new file mode 100644
index 0000000000..3849cc5230
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultFooter.jsp
@@ -0,0 +1,2 @@
+
+
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultHeader.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultHeader.jsp
new file mode 100644
index 0000000000..8a878c857d
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultHeader.jsp
@@ -0,0 +1,3 @@
+
+ Welcome to Spring MVC integration with Apache Tiles
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultMenu.jsp b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultMenu.jsp
new file mode 100644
index 0000000000..2c91eace85
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/templates/defaultMenu.jsp
@@ -0,0 +1,8 @@
+
diff --git a/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/tiles.xml b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/tiles.xml
new file mode 100644
index 0000000000..789fbd809a
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/WEB-INF/views/tiles/tiles.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-mvc-tiles/src/main/webapp/static/css/app.css b/spring-mvc-tiles/src/main/webapp/static/css/app.css
new file mode 100644
index 0000000000..9976e5406e
--- /dev/null
+++ b/spring-mvc-tiles/src/main/webapp/static/css/app.css
@@ -0,0 +1,36 @@
+.flex-container {
+ display: -webkit-flex;
+ display: flex;
+ -webkit-flex-flow: row wrap;
+ flex-flow: row wrap;
+ text-align: center;
+}
+
+.flex-container > * {
+ padding: 15px;
+ -webkit-flex: 1 100%;
+ flex: 1 100%;
+}
+
+.article {
+ text-align: left;
+}
+
+header {background: black;color:white;}
+footer {background: #aaa;color:white;}
+.nav {background:#eee;}
+
+.nav ul {
+ list-style-type: none;
+ padding: 0;
+}
+
+.nav ul a {
+ text-decoration: none;
+}
+
+@media all and (min-width: 768px) {
+ .nav {text-align:left;-webkit-flex: 1 auto;flex:1 auto;-webkit-order:1;order:1;}
+ .article {-webkit-flex:5 0px;flex:5 0px;-webkit-order:2;order:2;}
+ footer {-webkit-order:3;order:3;}
+}
\ No newline at end of file
diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java b/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java
index 8d967ed1ef..f5c1626989 100644
--- a/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java
+++ b/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java
@@ -31,9 +31,8 @@ public class SessionTimerInterceptor extends HandlerInterceptorAdapter {
request.setAttribute("executionTime", startTime);
if (UserInterceptor.isUserLogged()) {
session = request.getSession();
- log.info("Who is logged in: " + SecurityContextHolder.getContext().getAuthentication().getName());
- log.info("Time since last request in this session: "
- + (System.currentTimeMillis() - request.getSession().getLastAccessedTime()) + " ms");
+ log.info("Time since last request in this session: {} ms",
+ System.currentTimeMillis() - request.getSession().getLastAccessedTime());
if (System.currentTimeMillis() - session.getLastAccessedTime() > MAX_INACTIVE_SESSION_TIME) {
log.warn("Logging out, due to inactive session");
SecurityContextHolder.clearContext();
@@ -52,6 +51,6 @@ public class SessionTimerInterceptor extends HandlerInterceptorAdapter {
final ModelAndView model) throws Exception {
log.info("Post handle method - check execution time of handling");
long startTime = (Long) request.getAttribute("executionTime");
- log.info("Execution time for handling the request was: " + (System.currentTimeMillis() - startTime) + " ms");
+ log.info("Execution time for handling the request was: {} ms", System.currentTimeMillis() - startTime);
}
}
diff --git a/spring-thymeleaf/pom.xml b/spring-thymeleaf/pom.xml
index 35d8c37176..a13f1de4c7 100644
--- a/spring-thymeleaf/pom.xml
+++ b/spring-thymeleaf/pom.xml
@@ -5,185 +5,186 @@
spring-thymeleaf
0.1-SNAPSHOT
war
-
- 1.7
-
- 4.3.3.RELEASE
- 3.0.1
-
- 1.7.12
- 1.1.3
-
- 2.1.4.RELEASE
-
- 1.1.0.Final
- 5.1.2.Final
+
+ 1.8
+
+ 4.3.3.RELEASE
+ 3.0.1
+
+ 1.7.12
+ 1.1.3
+
+ 3.0.1.RELEASE
+
+ 1.1.0.Final
+ 5.1.2.Final
-
- 3.5.1
- 2.6
- 2.19.1
- 1.4.18
-
+
+ 3.5.1
+ 2.6
+ 2.19.1
+ 1.4.18
+
-
-
-
- org.springframework
- spring-context
- ${org.springframework-version}
-
-
-
- commons-logging
- commons-logging
-
-
-
-
- org.springframework
- spring-webmvc
- ${org.springframework-version}
-
-
-
- org.springframework.security
- spring-security-web
- 4.1.3.RELEASE
-
-
- org.springframework.security
- spring-security-config
- 4.1.3.RELEASE
-
-
-
- org.thymeleaf
- thymeleaf
- ${org.thymeleaf-version}
-
-
- org.thymeleaf
- thymeleaf-spring4
- ${org.thymeleaf-version}
-
-
-
-
- org.slf4j
- slf4j-api
- ${org.slf4j.version}
-
-
- ch.qos.logback
- logback-classic
- ${logback.version}
-
-
-
- org.slf4j
- jcl-over-slf4j
- ${org.slf4j.version}
-
-
-
- org.slf4j
- log4j-over-slf4j
- ${org.slf4j.version}
-
-
-
- javax.servlet
- javax.servlet-api
- ${javax.servlet-version}
- provided
-
-
-
- javax.validation
- validation-api
- ${javax.validation-version}
-
-
- org.hibernate
- hibernate-validator
- ${org.hibernate-version}
-
-
+
+
+
+ org.springframework
+ spring-context
+ ${org.springframework-version}
+
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.springframework
+ spring-webmvc
+ ${org.springframework-version}
+
+
+
+ org.springframework.security
+ spring-security-web
+ 4.1.3.RELEASE
+
+
+ org.springframework.security
+ spring-security-config
+ 4.1.3.RELEASE
+
+
+
+ org.thymeleaf
+ thymeleaf
+ ${org.thymeleaf-version}
+
+
+ org.thymeleaf
+ thymeleaf-spring4
+ ${org.thymeleaf-version}
+
+
+
+ org.slf4j
+ slf4j-api
+ ${org.slf4j.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${org.slf4j.version}
+
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${org.slf4j.version}
+
+
+
+ javax.servlet
+ javax.servlet-api
+ ${javax.servlet-version}
+ provided
+
+
+
+ javax.validation
+ validation-api
+ ${javax.validation-version}
+
+
+ org.hibernate
+ hibernate-validator
+ ${org.hibernate-version}
+
+
-
- org.springframework
- spring-test
- 4.1.3.RELEASE
- test
-
+
+ org.springframework
+ spring-test
+ 4.1.3.RELEASE
+ test
+
-
-
- org.springframework.security
- spring-security-test
- 4.1.3.RELEASE
- test
-
+
+
+ org.springframework.security
+ spring-security-test
+ 4.1.3.RELEASE
+ test
+
-
-
- junit
- junit
- 4.12
- test
-
+
+
+ junit
+ junit
+ 4.12
+ test
+
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- ${java-version}
- ${java-version}
-
-
-
- org.apache.maven.plugins
- maven-war-plugin
- ${maven-war-plugin.version}
-
- false
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
-
-
-
-
-
-
-
- org.codehaus.cargo
- cargo-maven2-plugin
- ${cargo-maven2-plugin.version}
-
- true
-
- jetty8x
- embedded
-
-
-
-
-
- 8082
-
-
-
-
-
-
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java-version}
+ ${java-version}
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+ ${cargo-maven2-plugin.version}
+
+ true
+
+ jetty8x
+ embedded
+
+
+
+
+
+ 8082
+
+
+
+
+
+
+
diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebApp.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebApp.java
index c7d5e33cb8..3104f45ab5 100644
--- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebApp.java
+++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebApp.java
@@ -9,28 +9,28 @@ import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatche
*/
public class WebApp extends AbstractAnnotationConfigDispatcherServletInitializer {
- public WebApp() {
- super();
- }
+ public WebApp() {
+ super();
+ }
- @Override
- protected Class>[] getRootConfigClasses() {
- return null;
- }
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return null;
+ }
- @Override
- protected Class>[] getServletConfigClasses() {
- return new Class>[] { WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class };
- }
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return new Class>[] { WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class };
+ }
- @Override
- protected String[] getServletMappings() {
- return new String[] { "/" };
- }
+ @Override
+ protected String[] getServletMappings() {
+ return new String[] { "/" };
+ }
- @Override
- protected void customizeRegistration(final Dynamic registration) {
- super.customizeRegistration(registration);
- }
+ @Override
+ protected void customizeRegistration(final Dynamic registration) {
+ super.customizeRegistration(registration);
+ }
}
diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java
index 50c9cf06fe..547d6deee9 100644
--- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java
+++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java
@@ -1,17 +1,23 @@
package com.baeldung.thymeleaf.config;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.format.FormatterRegistry;
+import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
+import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
-import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
+import org.thymeleaf.templatemode.TemplateMode;
+import org.thymeleaf.templateresolver.ITemplateResolver;
import com.baeldung.thymeleaf.formatter.NameFormatter;
@@ -22,35 +28,38 @@ import com.baeldung.thymeleaf.formatter.NameFormatter;
* Java configuration file that is used for Spring MVC and Thymeleaf
* configurations
*/
-public class WebMVCConfig extends WebMvcConfigurerAdapter {
+public class WebMVCConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {
- @Bean
- @Description("Thymeleaf Template Resolver")
- public ServletContextTemplateResolver templateResolver() {
- ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
- templateResolver.setPrefix("/WEB-INF/views/");
- templateResolver.setSuffix(".html");
- templateResolver.setTemplateMode("HTML5");
+ private ApplicationContext applicationContext;
- return templateResolver;
+ public void setApplicationContext(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
}
@Bean
- @Description("Thymeleaf Template Engine")
- public SpringTemplateEngine templateEngine() {
- SpringTemplateEngine templateEngine = new SpringTemplateEngine();
- templateEngine.setTemplateResolver(templateResolver());
-
- return templateEngine;
+ public ViewResolver viewResolver() {
+ ThymeleafViewResolver resolver = new ThymeleafViewResolver();
+ resolver.setTemplateEngine(templateEngine());
+ resolver.setCharacterEncoding("UTF-8");
+ resolver.setOrder(1);
+ return resolver;
}
@Bean
- @Description("Thymeleaf View Resolver")
- public ThymeleafViewResolver viewResolver() {
- ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
- viewResolver.setTemplateEngine(templateEngine());
- viewResolver.setOrder(1);
- return viewResolver;
+ public TemplateEngine templateEngine() {
+ SpringTemplateEngine engine = new SpringTemplateEngine();
+ engine.setEnableSpringELCompiler(true);
+ engine.setTemplateResolver(templateResolver());
+ return engine;
+ }
+
+ private ITemplateResolver templateResolver() {
+ SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
+ resolver.setApplicationContext(applicationContext);
+ resolver.setPrefix("/WEB-INF/views/");
+ resolver.setSuffix(".html");
+ resolver.setTemplateMode(TemplateMode.HTML);
+ return resolver;
}
@Bean
diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java
index 00c42831de..37844a2976 100644
--- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java
+++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCSecurity.java
@@ -14,7 +14,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebMVCSecurity extends WebSecurityConfigurerAdapter {
-
+
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
index 912eb521f4..da34b2d7b0 100644
--- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
+++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/controller/StudentController.java
@@ -20,50 +20,50 @@ import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class StudentController {
- @RequestMapping(value = "/saveStudent", method = RequestMethod.POST)
- public String saveStudent(@Valid @ModelAttribute Student student, BindingResult errors, Model model) {
- if (!errors.hasErrors()) {
- // get mock objects
- List students = buildStudents();
- // add current student
- students.add(student);
- model.addAttribute("students", students);
- }
- return ((errors.hasErrors()) ? "addStudent" : "listStudents");
- }
+ @RequestMapping(value = "/saveStudent", method = RequestMethod.POST)
+ public String saveStudent(@Valid @ModelAttribute Student student, BindingResult errors, Model model) {
+ if (!errors.hasErrors()) {
+ // get mock objects
+ List students = buildStudents();
+ // add current student
+ students.add(student);
+ model.addAttribute("students", students);
+ }
+ return ((errors.hasErrors()) ? "addStudent" : "listStudents");
+ }
- @RequestMapping(value = "/addStudent", method = RequestMethod.GET)
- public String addStudent(Model model) {
- model.addAttribute("student", new Student());
- return "addStudent";
- }
+ @RequestMapping(value = "/addStudent", method = RequestMethod.GET)
+ public String addStudent(Model model) {
+ model.addAttribute("student", new Student());
+ return "addStudent";
+ }
- @RequestMapping(value = "/listStudents", method = RequestMethod.GET)
- public String listStudent(Model model) {
+ @RequestMapping(value = "/listStudents", method = RequestMethod.GET)
+ public String listStudent(Model model) {
- model.addAttribute("students", buildStudents());
+ model.addAttribute("students", buildStudents());
- return "listStudents";
- }
+ return "listStudents";
+ }
- private List buildStudents() {
- List students = new ArrayList();
+ private List buildStudents() {
+ List students = new ArrayList();
- Student student1 = new Student();
- student1.setId(1001);
- student1.setName("John Smith");
- student1.setGender('M');
- student1.setPercentage(Float.valueOf("80.45"));
+ Student student1 = new Student();
+ student1.setId(1001);
+ student1.setName("John Smith");
+ student1.setGender('M');
+ student1.setPercentage(Float.valueOf("80.45"));
- students.add(student1);
+ students.add(student1);
- Student student2 = new Student();
- student2.setId(1002);
- student2.setName("Jane Williams");
- student2.setGender('F');
- student2.setPercentage(Float.valueOf("60.25"));
+ Student student2 = new Student();
+ student2.setId(1002);
+ student2.setName("Jane Williams");
+ student2.setGender('F');
+ student2.setPercentage(Float.valueOf("60.25"));
- students.add(student2);
- return students;
- }
+ students.add(student2);
+ return students;
+ }
}
diff --git a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java
index bce99f286c..202c04358a 100644
--- a/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java
+++ b/spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/model/Student.java
@@ -12,49 +12,49 @@ import javax.validation.constraints.NotNull;
*/
public class Student implements Serializable {
- private static final long serialVersionUID = -8582553475226281591L;
+ private static final long serialVersionUID = -8582553475226281591L;
- @NotNull(message = "Student ID is required.")
- @Min(value = 1000, message = "Student ID must be at least 4 digits.")
- private Integer id;
+ @NotNull(message = "Student ID is required.")
+ @Min(value = 1000, message = "Student ID must be at least 4 digits.")
+ private Integer id;
- @NotNull(message = "Student name is required.")
- private String name;
+ @NotNull(message = "Student name is required.")
+ private String name;
- @NotNull(message = "Student gender is required.")
- private Character gender;
+ @NotNull(message = "Student gender is required.")
+ private Character gender;
- private Float percentage;
+ private Float percentage;
- public Integer getId() {
- return id;
- }
+ public Integer getId() {
+ return id;
+ }
- public void setId(Integer id) {
- this.id = id;
- }
+ public void setId(Integer id) {
+ this.id = id;
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
- public Character getGender() {
- return gender;
- }
+ public Character getGender() {
+ return gender;
+ }
- public void setGender(Character gender) {
- this.gender = gender;
- }
+ public void setGender(Character gender) {
+ this.gender = gender;
+ }
- public Float getPercentage() {
- return percentage;
- }
+ public Float getPercentage() {
+ return percentage;
+ }
- public void setPercentage(Float percentage) {
- this.percentage = percentage;
- }
+ public void setPercentage(Float percentage) {
+ this.percentage = percentage;
+ }
}
diff --git a/spring-thymeleaf/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java b/spring-thymeleaf/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java
index bd70881dd8..46a28c3c74 100644
--- a/spring-thymeleaf/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java
+++ b/spring-thymeleaf/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java
@@ -30,17 +30,17 @@ import com.baeldung.thymeleaf.config.WebMVCSecurity;
@WebAppConfiguration
@ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class })
public class CsrfEnabledIntegrationTest {
-
- @Autowired
+
+ @Autowired
WebApplicationContext wac;
@Autowired
MockHttpSession session;
private MockMvc mockMvc;
-
+
@Autowired
private Filter springSecurityFilterChain;
-
+
protected RequestPostProcessor testUser() {
return user("user1").password("user1Pass").roles("USER");
}
@@ -52,12 +52,12 @@ public class CsrfEnabledIntegrationTest {
@Test
public void addStudentWithoutCSRF() throws Exception {
- mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON).param("id", "1234567").param("name", "Joe").param("gender", "M").with(testUser())).andExpect(status().isForbidden());
+ mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON).param("id", "1234567").param("name", "Joe").param("gender", "M").with(testUser())).andExpect(status().isForbidden());
}
@Test
public void addStudentWithCSRF() throws Exception {
- mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON).param("id", "1234567").param("name", "Joe").param("gender", "M").with(testUser()).with(csrf())).andExpect(status().isOk());
+ mockMvc.perform(post("/saveStudent").contentType(MediaType.APPLICATION_JSON).param("id", "1234567").param("name", "Joe").param("gender", "M").with(testUser()).with(csrf())).andExpect(status().isOk());
}
}
diff --git a/spring-userservice/.springBeans b/spring-userservice/.springBeans
new file mode 100644
index 0000000000..ff32b84d3b
--- /dev/null
+++ b/spring-userservice/.springBeans
@@ -0,0 +1,15 @@
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-userservice/README.md b/spring-userservice/README.md
new file mode 100644
index 0000000000..097afc5fc1
--- /dev/null
+++ b/spring-userservice/README.md
@@ -0,0 +1 @@
+spring-userservice is using a in memory derby db. Right click -> run on server to run the project
\ No newline at end of file
diff --git a/spring-userservice/pom.xml b/spring-userservice/pom.xml
new file mode 100644
index 0000000000..93b01ee49c
--- /dev/null
+++ b/spring-userservice/pom.xml
@@ -0,0 +1,320 @@
+
+ 4.0.0
+ spring-userservice
+ spring-userservice
+ 0.0.1-SNAPSHOT
+ war
+
+
+
+
+
+
+ org.springframework
+ spring-orm
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-context
+ ${org.springframework.version}
+
+
+
+
+
+ org.hibernate
+ hibernate-entitymanager
+ ${hibernate.version}
+
+
+ org.hibernate
+ hibernate-ehcache
+ ${hibernate.version}
+
+
+ xml-apis
+ xml-apis
+ 1.4.01
+
+
+ org.javassist
+ javassist
+ ${javassist.version}
+
+
+ mysql
+ mysql-connector-java
+ ${mysql-connector-java.version}
+ runtime
+
+
+ org.springframework.data
+ spring-data-jpa
+ ${spring-data-jpa.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+
+
+
+ org.hibernate
+ hibernate-validator
+ ${hibernate-validator.version}
+
+
+ javax.el
+ javax.el-api
+ 2.2.5
+
+
+
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+ test
+
+
+
+ org.springframework
+ spring-test
+ ${org.springframework.version}
+ test
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+ org.hamcrest
+ hamcrest-core
+ ${org.hamcrest.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-library
+ ${org.hamcrest.version}
+ test
+
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+
+ org.springframework
+ spring-core
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-web
+ ${org.springframework.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${org.springframework.version}
+
+
+
+ org.springframework.security
+ spring-security-core
+ ${org.springframework.security.version}
+
+
+ org.springframework.security
+ spring-security-web
+ ${org.springframework.security.version}
+
+
+ org.springframework.security
+ spring-security-config
+ ${org.springframework.security.version}
+
+
+
+ org.apache.derby
+ derby
+ 10.12.1.1
+
+
+ org.apache.derby
+ derbyclient
+ 10.12.1.1
+
+
+ org.apache.derby
+ derbynet
+ 10.12.1.1
+
+
+ org.apache.derby
+ derbytools
+ 10.12.1.1
+
+
+ taglibs
+ standard
+ 1.1.2
+
+
+ org.springframework.security
+ spring-security-taglibs
+ 4.1.3.RELEASE
+
+
+ javax.servlet.jsp.jstl
+ jstl-api
+ 1.2
+
+
+ org.springframework.boot
+ spring-boot-test
+ 1.4.1.RELEASE
+
+
+ org.springframework.boot
+ spring-boot
+ 1.4.1.RELEASE
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+
+
+
+
+ spring-userservice
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+ ${cargo-maven2-plugin.version}
+
+ true
+
+ jetty8x
+ embedded
+
+
+
+
+
+
+ 8082
+
+
+
+
+
+
+
+
+
+
+
+ 4.1.3.RELEASE
+ 4.3.2.RELEASE
+ 3.20.0-GA
+
+
+ 5.2.2.Final
+ 5.1.38
+ 1.10.2.RELEASE
+ 1.4.192
+
+
+ 1.7.13
+ 1.1.3
+
+
+ 5.2.2.Final
+
+
+ 19.0
+ 3.4
+
+
+ 1.3
+ 4.12
+ 1.10.19
+
+ 4.4.1
+ 4.5
+
+ 2.9.0
+
+
+ 3.5.1
+ 2.6
+ 2.19.1
+ 2.7
+ 1.4.18
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-userservice/src/main/java/org/baeldung/custom/config/MvcConfig.java b/spring-userservice/src/main/java/org/baeldung/custom/config/MvcConfig.java
new file mode 100644
index 0000000000..4a9e737a92
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/custom/config/MvcConfig.java
@@ -0,0 +1,42 @@
+package org.baeldung.custom.config;
+
+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.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+import org.springframework.web.servlet.view.JstlView;
+
+@EnableWebMvc
+@Configuration
+@ComponentScan(basePackages = { "org.baeldung.security" })
+public class MvcConfig extends WebMvcConfigurerAdapter {
+
+ public MvcConfig() {
+ super();
+ }
+
+ @Override
+ public void addViewControllers(final ViewControllerRegistry registry) {
+ super.addViewControllers(registry);
+
+ registry.addViewController("/");
+ registry.addViewController("/index");
+ registry.addViewController("/login");
+ registry.addViewController("/register");
+ }
+
+ @Bean
+ public ViewResolver viewResolver() {
+ final InternalResourceViewResolver bean = new InternalResourceViewResolver();
+
+ bean.setViewClass(JstlView.class);
+ bean.setPrefix("/WEB-INF/view/");
+ bean.setSuffix(".jsp");
+
+ return bean;
+ }
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/custom/config/PersistenceDerbyJPAConfig.java b/spring-userservice/src/main/java/org/baeldung/custom/config/PersistenceDerbyJPAConfig.java
new file mode 100644
index 0000000000..6be7053b78
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/custom/config/PersistenceDerbyJPAConfig.java
@@ -0,0 +1,89 @@
+package org.baeldung.custom.config;
+
+import java.util.Properties;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+
+import org.baeldung.user.dao.MyUserDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.google.common.base.Preconditions;
+
+@Configuration
+@EnableTransactionManagement
+@PropertySource({ "classpath:persistence-derby.properties" })
+public class PersistenceDerbyJPAConfig {
+
+ @Autowired
+ private Environment env;
+
+ public PersistenceDerbyJPAConfig() {
+ super();
+ }
+
+ // beans
+
+ @Bean
+ public LocalContainerEntityManagerFactoryBean myEmf() {
+ final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
+ em.setDataSource(dataSource());
+ em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
+
+ final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ em.setJpaVendorAdapter(vendorAdapter);
+ em.setJpaProperties(additionalProperties());
+
+ return em;
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ final DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
+ dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
+ dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
+ dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
+
+ return dataSource;
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
+ final JpaTransactionManager transactionManager = new JpaTransactionManager();
+ transactionManager.setEntityManagerFactory(emf);
+ return transactionManager;
+ }
+
+ @Bean
+ public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ final Properties additionalProperties() {
+ final Properties hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
+ hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
+ hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
+ hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
+ // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
+ return hibernateProperties;
+ }
+
+ @Bean
+ public MyUserDAO myUserDAO() {
+ final MyUserDAO myUserDAO = new MyUserDAO();
+ return myUserDAO;
+ }
+}
\ No newline at end of file
diff --git a/spring-userservice/src/main/java/org/baeldung/custom/config/SecSecurityConfig.java b/spring-userservice/src/main/java/org/baeldung/custom/config/SecSecurityConfig.java
new file mode 100644
index 0000000000..44df02980f
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/custom/config/SecSecurityConfig.java
@@ -0,0 +1,75 @@
+package org.baeldung.custom.config;
+
+import org.baeldung.security.MyUserDetailsService;
+import org.baeldung.user.service.MyUserService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+@EnableWebSecurity
+@Profile("!https")
+public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ public SecSecurityConfig() {
+ super();
+ }
+
+ @Override
+ protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
+ // @formatter:off
+ auth.authenticationProvider(authenticationProvider());
+ // @formatter:on
+ }
+
+ @Override
+ protected void configure(final HttpSecurity http) throws Exception {
+ // @formatter:off
+ http
+ .csrf().disable()
+ .authorizeRequests()
+ .antMatchers("/*").permitAll()
+ .and()
+ .formLogin()
+ .loginPage("/login")
+ .loginProcessingUrl("/login")
+ .defaultSuccessUrl("/",true)
+ .failureUrl("/login?error=true")
+ .and()
+ .logout()
+ .logoutUrl("/logout")
+ .deleteCookies("JSESSIONID")
+ .logoutSuccessUrl("/");
+ // @formatter:on
+ }
+
+ @Bean
+ public DaoAuthenticationProvider authenticationProvider() {
+ final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
+ authProvider.setUserDetailsService(myUserDetailsService());
+ authProvider.setPasswordEncoder(encoder());
+ return authProvider;
+ }
+
+ @Bean
+ public PasswordEncoder encoder() {
+ return new BCryptPasswordEncoder(11);
+ }
+
+ @Bean
+ public MyUserDetailsService myUserDetailsService() {
+ return new MyUserDetailsService();
+ }
+
+ @Bean
+ public MyUserService myUserService() {
+ return new MyUserService();
+ }
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/persistence/model/MyUser.java b/spring-userservice/src/main/java/org/baeldung/persistence/model/MyUser.java
new file mode 100644
index 0000000000..804d391641
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/persistence/model/MyUser.java
@@ -0,0 +1,50 @@
+package org.baeldung.persistence.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(schema = "spring_custom_user_service")
+public class MyUser {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private int id;
+
+ @Column(unique = true, nullable = false)
+ private String username;
+
+ @Column(nullable = false)
+ private String password;
+
+ public MyUser() {
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(final String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/security/MyUserDetailsService.java b/spring-userservice/src/main/java/org/baeldung/security/MyUserDetailsService.java
new file mode 100644
index 0000000000..fe97984af8
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/security/MyUserDetailsService.java
@@ -0,0 +1,35 @@
+package org.baeldung.security;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.baeldung.persistence.model.MyUser;
+import org.baeldung.user.dao.MyUserDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service("userDetailsService")
+public class MyUserDetailsService implements UserDetailsService {
+
+ @Autowired
+ MyUserDAO myUserDAO;
+
+ @Override
+ public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
+ final MyUser user = myUserDAO.findByUsername(username);
+
+ if (user == null) {
+ throw new UsernameNotFoundException("No user found with username: " + username);
+ }
+ return new User(user.getUsername(), user.getPassword(), Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
+
+ }
+
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/security/UserController.java b/spring-userservice/src/main/java/org/baeldung/security/UserController.java
new file mode 100644
index 0000000000..b1c96e72c0
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/security/UserController.java
@@ -0,0 +1,52 @@
+package org.baeldung.security;
+
+import javax.annotation.Resource;
+
+import org.baeldung.user.service.MyUserService;
+import org.baeldung.web.MyUserDto;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+public class UserController {
+
+ @Resource
+ MyUserService myUserService;
+
+ @RequestMapping(value = "/register", method = RequestMethod.POST)
+ public String registerUserAccount(final MyUserDto accountDto, final Model model) {
+ final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ model.addAttribute("name", auth.getName());
+ try {
+ myUserService.registerNewUserAccount(accountDto);
+ model.addAttribute("message", "Registration successful");
+ return "index";
+ }
+ catch(final Exception exc){
+ model.addAttribute("message", "Registration failed");
+
+ return "index";
+ }
+ }
+
+ @RequestMapping(value = "/", method = RequestMethod.GET)
+ public String getHomepage(final Model model) {
+ final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ model.addAttribute("name", auth.getName());
+ return "index";
+ }
+
+ @RequestMapping(value = "/register", method = RequestMethod.GET)
+ public String getRegister() {
+ return "register";
+ }
+
+ @RequestMapping(value = "/login", method = RequestMethod.GET)
+ public String getLogin() {
+ return "login";
+ }
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/user/dao/MyUserDAO.java b/spring-userservice/src/main/java/org/baeldung/user/dao/MyUserDAO.java
new file mode 100644
index 0000000000..4cc9f61b4a
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/user/dao/MyUserDAO.java
@@ -0,0 +1,46 @@
+package org.baeldung.user.dao;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+
+import org.baeldung.persistence.model.MyUser;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class MyUserDAO {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ public MyUser findByUsername(final String username) {
+ final Query query = entityManager.createQuery("from MyUser where username=:username", MyUser.class);
+ query.setParameter("username", username);
+ final List result = query.getResultList();
+ if (result != null && result.size() > 0) {
+ return result.get(0);
+ } else
+ return null;
+ }
+
+ public MyUser save(final MyUser user) {
+ entityManager.persist(user);
+ return user;
+ }
+
+ public void removeUserByUsername(String username) {
+ final Query query = entityManager.createQuery("delete from MyUser where username=:username");
+ query.setParameter("username", username);
+ query.executeUpdate();
+ }
+
+ public EntityManager getEntityManager() {
+ return entityManager;
+ }
+
+ public void setEntityManager(final EntityManager entityManager) {
+ this.entityManager = entityManager;
+ }
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/user/service/MyUserService.java b/spring-userservice/src/main/java/org/baeldung/user/service/MyUserService.java
new file mode 100644
index 0000000000..1e05541998
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/user/service/MyUserService.java
@@ -0,0 +1,49 @@
+package org.baeldung.user.service;
+
+import org.baeldung.persistence.model.MyUser;
+import org.baeldung.user.dao.MyUserDAO;
+import org.baeldung.web.MyUserDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional
+public class MyUserService {
+
+ @Autowired
+ private PasswordEncoder passwordEncoder;
+
+ @Autowired
+ MyUserDAO myUserDAO;
+
+ public MyUser registerNewUserAccount(final MyUserDto accountDto) throws Exception {
+ if (usernameExists(accountDto.getUsername())) {
+ throw new Exception("There is an account with that username: " + accountDto.getUsername());
+ }
+ final MyUser user = new MyUser();
+
+ user.setUsername(accountDto.getUsername());
+ user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
+ return myUserDAO.save(user);
+ }
+
+ public MyUser getUserByUsername(final String username) {
+ final MyUser user = myUserDAO.findByUsername(username);
+ return user;
+ }
+
+ public void removeUserByUsername(String username){
+ myUserDAO.removeUserByUsername(username);
+ }
+
+ private boolean usernameExists(final String username) {
+ final MyUser user = myUserDAO.findByUsername(username);
+ if (user != null) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/spring-userservice/src/main/java/org/baeldung/web/MyUserDto.java b/spring-userservice/src/main/java/org/baeldung/web/MyUserDto.java
new file mode 100644
index 0000000000..c572208913
--- /dev/null
+++ b/spring-userservice/src/main/java/org/baeldung/web/MyUserDto.java
@@ -0,0 +1,29 @@
+package org.baeldung.web;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+public class MyUserDto {
+ @NotNull
+ @Size(min = 1)
+ private String username;
+
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(final String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+}
diff --git a/spring-userservice/src/main/resources/persistence-derby.properties b/spring-userservice/src/main/resources/persistence-derby.properties
new file mode 100644
index 0000000000..e808fdc288
--- /dev/null
+++ b/spring-userservice/src/main/resources/persistence-derby.properties
@@ -0,0 +1,12 @@
+# jdbc.X
+jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver
+jdbc.url=jdbc:derby:memory:spring_custom_user_service;create=true
+jdbc.user=tutorialuser
+jdbc.pass=tutorialpass
+
+# hibernate.X
+hibernate.dialect=org.hibernate.dialect.DerbyDialect
+hibernate.show_sql=false
+hibernate.hbm2ddl.auto=create
+hibernate.cache.use_second_level_cache=false
+hibernate.cache.use_query_cache=false
\ No newline at end of file
diff --git a/spring-userservice/src/main/webapp/META-INF/MANIFEST.MF b/spring-userservice/src/main/webapp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..254272e1c0
--- /dev/null
+++ b/spring-userservice/src/main/webapp/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/spring-userservice/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml b/spring-userservice/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml
new file mode 100644
index 0000000000..25d1d4d22f
--- /dev/null
+++ b/spring-userservice/src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /WEB-INF/views/
+
+
+ .jsp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${hibernate.hbm2ddl.auto}
+ ${hibernate.dialect}
+ ${hibernate.cache.use_second_level_cache}
+ ${hibernate.cache.use_query_cache}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-userservice/src/main/webapp/WEB-INF/views/index.jsp b/spring-userservice/src/main/webapp/WEB-INF/views/index.jsp
new file mode 100644
index 0000000000..0c89257cd2
--- /dev/null
+++ b/spring-userservice/src/main/webapp/WEB-INF/views/index.jsp
@@ -0,0 +1,35 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+<%@ taglib prefix="c"
+ uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
+
+
+
+
+
+Welcome!
+
+
+
+
+
+
+
+Register
+
+
+Login
+
+
+${message }
+
+
+Hello, ${name }!
+
+
+Logout
+
+
+
+
\ No newline at end of file
diff --git a/spring-userservice/src/main/webapp/WEB-INF/views/login.jsp b/spring-userservice/src/main/webapp/WEB-INF/views/login.jsp
new file mode 100644
index 0000000000..29431f426d
--- /dev/null
+++ b/spring-userservice/src/main/webapp/WEB-INF/views/login.jsp
@@ -0,0 +1,29 @@
+<%@ taglib prefix="c"
+ uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+
+
+
+ Login
+
+
+ Username or password invalid!
+
+
\ No newline at end of file
diff --git a/spring-userservice/src/main/webapp/WEB-INF/views/register.jsp b/spring-userservice/src/main/webapp/WEB-INF/views/register.jsp
new file mode 100644
index 0000000000..e6e9d373a0
--- /dev/null
+++ b/spring-userservice/src/main/webapp/WEB-INF/views/register.jsp
@@ -0,0 +1,23 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+<%@ taglib prefix="c"
+ uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+
+
+Welcome!
+
+
+
+
+
+Register here:
+
+
+
+
\ No newline at end of file
diff --git a/spring-userservice/src/main/webapp/WEB-INF/web.xml b/spring-userservice/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..b526774179
--- /dev/null
+++ b/spring-userservice/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,51 @@
+
+
+
+ Spring MVC Application
+
+
+
+
+
+ mvc-dispatcher
+ org.springframework.web.servlet.DispatcherServlet
+ 1
+
+
+ mvc-dispatcher
+ /
+
+
+
+
+ springSecurityFilterChain
+ org.springframework.web.filter.DelegatingFilterProxy
+
+
+ springSecurityFilterChain
+ /*
+
+
+
+ index.jsp
+
+
+
\ No newline at end of file
diff --git a/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceTest.java b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceTest.java
new file mode 100644
index 0000000000..6e1cd67e06
--- /dev/null
+++ b/spring-userservice/src/test/java/org/baeldung/userservice/CustomUserDetailsServiceTest.java
@@ -0,0 +1,85 @@
+package org.baeldung.userservice;
+
+import org.baeldung.custom.config.MvcConfig;
+import org.baeldung.custom.config.PersistenceDerbyJPAConfig;
+import org.baeldung.custom.config.SecSecurityConfig;
+import org.baeldung.user.service.MyUserService;
+import org.baeldung.web.MyUserDto;
+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.dao.DuplicateKeyException;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import static org.junit.Assert.*;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringApplicationConfiguration(classes = { MvcConfig.class, PersistenceDerbyJPAConfig.class, SecSecurityConfig.class })
+@WebAppConfiguration
+public class CustomUserDetailsServiceTest {
+
+ private static final Logger LOG = Logger.getLogger("CustomUserDetailsServiceTest");
+
+ public static final String USERNAME = "user";
+ public static final String PASSWORD = "pass";
+ public static final String USERNAME2 = "user2";
+
+ @Autowired
+ MyUserService myUserService;
+
+ @Autowired
+ AuthenticationProvider authenticationProvider;
+
+ @Test
+ public void givenExistingUser_whenAuthenticate_thenRetrieveFromDb() {
+ try {
+ MyUserDto userDTO = new MyUserDto();
+ userDTO.setUsername(USERNAME);
+ userDTO.setPassword(PASSWORD);
+
+ myUserService.registerNewUserAccount(userDTO);
+
+ UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(USERNAME, PASSWORD);
+ Authentication authentication = authenticationProvider.authenticate(auth);
+
+ assertEquals(authentication.getName(), USERNAME);
+
+ } catch (Exception exc) {
+ LOG.log(Level.SEVERE, "Error creating account");
+ } finally {
+ myUserService.removeUserByUsername(USERNAME);
+ }
+ }
+
+ @Test (expected = BadCredentialsException.class)
+ public void givenIncorrectUser_whenAuthenticate_thenBadCredentialsException() {
+ try {
+ MyUserDto userDTO = new MyUserDto();
+ userDTO.setUsername(USERNAME);
+ userDTO.setPassword(PASSWORD);
+
+ try {
+ myUserService.registerNewUserAccount(userDTO);
+ }
+ catch (Exception exc) {
+ LOG.log(Level.SEVERE, "Error creating account");
+ }
+
+ UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(USERNAME2, PASSWORD);
+ Authentication authentication = authenticationProvider.authenticate(auth);
+ }
+ finally {
+ myUserService.removeUserByUsername(USERNAME);
+ }
+ }
+
+}