diff --git a/JGit/README.md b/JGit/README.md
new file mode 100644
index 0000000000..5c65f1101b
--- /dev/null
+++ b/JGit/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [A Guide to JGit](http://www.baeldung.com/jgit)
diff --git a/algorithms/README.md b/algorithms/README.md
new file mode 100644
index 0000000000..4789768fad
--- /dev/null
+++ b/algorithms/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra)
diff --git a/algorithms/pom.xml b/algorithms/pom.xml
index 0c85a19534..f72457650a 100644
--- a/algorithms/pom.xml
+++ b/algorithms/pom.xml
@@ -41,4 +41,23 @@
-
\ No newline at end of file
+
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ 2.7
+
+
+
+ com/baeldung/algorithms/dijkstra/*
+
+
+ com/baeldung/algorithms/dijkstra/*
+
+
+
+
+
+
+
diff --git a/apache-bval/README.md b/apache-bval/README.md
new file mode 100644
index 0000000000..80ea149993
--- /dev/null
+++ b/apache-bval/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Intro to Apache BVal](http://www.baeldung.com/apache-bval)
diff --git a/apache-bval/pom.xml b/apache-bval/pom.xml
new file mode 100644
index 0000000000..5d556af56f
--- /dev/null
+++ b/apache-bval/pom.xml
@@ -0,0 +1,51 @@
+
+ 4.0.0
+ apache-bval
+ apache-bval
+ 0.0.1-SNAPSHOT
+
+
+
+ org.apache.bval
+ bval-jsr
+ ${bval.version}
+
+
+ javax.validation
+ validation-api
+ 1.1.0.Final
+
+
+ org.apache.bval
+ bval-extras
+ ${bval.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ 1.8
+
+
+
+
+
+ 3.6.0
+ 4.12
+ 1.1.2
+
+
\ No newline at end of file
diff --git a/apache-bval/src/main/java/com/baeldung/model/User.java b/apache-bval/src/main/java/com/baeldung/model/User.java
new file mode 100644
index 0000000000..477136ddb4
--- /dev/null
+++ b/apache-bval/src/main/java/com/baeldung/model/User.java
@@ -0,0 +1,120 @@
+package com.baeldung.model;
+
+import java.io.File;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import org.apache.bval.constraints.Email;
+import org.apache.bval.constraints.NotEmpty;
+import org.apache.bval.extras.constraints.checkdigit.IBAN;
+import org.apache.bval.extras.constraints.creditcard.Visa;
+import org.apache.bval.extras.constraints.file.Directory;
+import org.apache.bval.extras.constraints.net.InetAddress;
+
+import com.baeldung.validation.Password;
+
+public class User {
+ @NotNull
+ @Email
+ private String email;
+
+ @NotEmpty
+ @Password
+ private String password;
+
+ @Size(min = 1, max = 20)
+ private String name;
+
+ @Min(18)
+ private int age;
+
+ @Visa
+ private String cardNumber = "";
+
+ @IBAN
+ private String iban = "";
+
+ @InetAddress
+ private String website = "";
+
+ @Directory
+ private File mainDirectory=new File(".");
+
+ public User() {
+ }
+
+ public User(String email, String password, String name, int age) {
+ super();
+ this.email = email;
+ this.password = password;
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getCardNumber() {
+ return cardNumber;
+ }
+
+ public void setCardNumber(String cardNumber) {
+ this.cardNumber = cardNumber;
+ }
+
+ public String getIban() {
+ return iban;
+ }
+
+ public void setIban(String iban) {
+ this.iban = iban;
+ }
+
+ public String getWebsite() {
+ return website;
+ }
+
+ public void setWebsite(String website) {
+ this.website = website;
+ }
+
+ public File getMainDirectory() {
+ return mainDirectory;
+ }
+
+ public void setMainDirectory(File mainDirectory) {
+ this.mainDirectory = mainDirectory;
+ }
+
+}
diff --git a/apache-bval/src/main/java/com/baeldung/validation/Password.java b/apache-bval/src/main/java/com/baeldung/validation/Password.java
new file mode 100644
index 0000000000..4ae06b2fb0
--- /dev/null
+++ b/apache-bval/src/main/java/com/baeldung/validation/Password.java
@@ -0,0 +1,25 @@
+package com.baeldung.validation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+import static java.lang.annotation.ElementType.*;
+
+@Constraint(validatedBy = { PasswordValidator.class })
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Password {
+ String message() default "Invalid password";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ int length() default 6;
+
+ int nonAlpha() default 1;
+}
diff --git a/apache-bval/src/main/java/com/baeldung/validation/PasswordValidator.java b/apache-bval/src/main/java/com/baeldung/validation/PasswordValidator.java
new file mode 100644
index 0000000000..19038d04d5
--- /dev/null
+++ b/apache-bval/src/main/java/com/baeldung/validation/PasswordValidator.java
@@ -0,0 +1,35 @@
+package com.baeldung.validation;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+public class PasswordValidator implements ConstraintValidator {
+
+ private int length;
+ private int nonAlpha;
+
+ @Override
+ public void initialize(Password password) {
+ this.length = password.length();
+ this.nonAlpha = password.nonAlpha();
+
+ }
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ if (value.length() < length) {
+ return false;
+ }
+ int nonAlphaNr = 0;
+ for (int i = 0; i < value.length(); i++) {
+ if (!Character.isLetterOrDigit(value.charAt(i))) {
+ nonAlphaNr++;
+ }
+ }
+ if (nonAlphaNr < nonAlpha) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/apache-bval/src/test/java/com/baeldung/validation/ValidationTest.java b/apache-bval/src/test/java/com/baeldung/validation/ValidationTest.java
new file mode 100644
index 0000000000..cd58d4460a
--- /dev/null
+++ b/apache-bval/src/test/java/com/baeldung/validation/ValidationTest.java
@@ -0,0 +1,97 @@
+package com.baeldung.validation;
+
+import java.io.File;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+import org.apache.bval.jsr.ApacheValidationProvider;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import com.baeldung.model.User;
+
+public class ValidationTest {
+ private static ValidatorFactory validatorFactory;
+ private static Validator validator;
+
+ @BeforeClass
+ public static void setup() {
+ validatorFactory = Validation.byProvider(ApacheValidationProvider.class)
+ .configure()
+ .buildValidatorFactory();
+ validator = validatorFactory.getValidator();
+ }
+
+ @Test
+ public void givenUser_whenValidate_thenValidationViolations() {
+ User user = new User("ana@yahoo.com", "pass", "nameTooLong_______________", 15);
+
+ Set> violations = validator.validate(user);
+ assertTrue("no violations", violations.size() > 0);
+ }
+
+ @Test
+ public void givenInvalidAge_whenValidateProperty_thenConstraintViolation() {
+ User user = new User("ana@yahoo.com", "pass", "Ana", 12);
+
+ Set> propertyViolations = validator.validateProperty(user, "age");
+ assertEquals("size is not 1", 1, propertyViolations.size());
+ }
+
+ @Test
+ public void givenValidAge_whenValidateValue_thenNoConstraintViolation() {
+ User user = new User("ana@yahoo.com", "pass", "Ana", 18);
+
+ Set> valueViolations = validator.validateValue(User.class, "age", 20);
+ assertEquals("size is not 0", 0, valueViolations.size());
+ }
+
+ @Test
+ public void whenValidateNonJSR_thenCorrect() {
+ User user = new User("ana@yahoo.com", "pass", "Ana", 20);
+ user.setCardNumber("1234");
+ user.setIban("1234");
+ user.setWebsite("10.0.2.50");
+ user.setMainDirectory(new File("."));
+
+ Set> violations = validator.validateProperty(user, "iban");
+ assertEquals("size is not 1", 1, violations.size());
+
+ violations = validator.validateProperty(user, "website");
+ assertEquals("size is not 0", 0, violations.size());
+
+ violations = validator.validateProperty(user, "mainDirectory");
+ assertEquals("size is not 0", 0, violations.size());
+ }
+
+ @Test
+ public void givenInvalidPassword_whenValidatePassword_thenConstraintViolation() {
+ User user = new User("ana@yahoo.com", "password", "Ana", 20);
+ Set> violations = validator.validateProperty(user, "password");
+ assertEquals("message incorrect", "Invalid password", violations.iterator()
+ .next()
+ .getMessage());
+ }
+
+ @Test
+ public void givenValidPassword_whenValidatePassword_thenNoConstraintViolation() {
+ User user = new User("ana@yahoo.com", "password#", "Ana", 20);
+
+ Set> violations = validator.validateProperty(user, "password");
+ assertEquals("size is not 0", 0, violations.size());
+ }
+
+ @AfterClass
+ public static void close() {
+ if (validatorFactory != null) {
+ validatorFactory.close();
+ }
+ }
+}
diff --git a/apache-solrj/pom.xml b/apache-solrj/pom.xml
new file mode 100644
index 0000000000..74daeae55c
--- /dev/null
+++ b/apache-solrj/pom.xml
@@ -0,0 +1,50 @@
+
+ 4.0.0
+ com.baeldung
+ apache-solrj
+ 0.0.1-SNAPSHOT
+ jar
+ apache-solrj
+
+
+ 4.12
+ 2.19.1
+
+
+
+
+ org.apache.solr
+ solr-solrj
+ 6.4.0
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ 1.8
+
+ **/*IntegrationTest.java
+ **/*LiveTest.java
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apache-solrj/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java b/apache-solrj/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java
new file mode 100644
index 0000000000..f2d21f0993
--- /dev/null
+++ b/apache-solrj/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java
@@ -0,0 +1,43 @@
+package com.baeldung.solrjava;
+
+import java.io.IOException;
+
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.XMLResponseParser;
+import org.apache.solr.common.SolrInputDocument;
+
+public class SolrJavaIntegration {
+
+ private HttpSolrClient solrClient;
+
+ public SolrJavaIntegration(String clientUrl) {
+
+ solrClient = new HttpSolrClient.Builder(clientUrl).build();
+ solrClient.setParser(new XMLResponseParser());
+ }
+
+ public void addSolrDocument(String documentId, String itemName, String itemPrice) throws SolrServerException, IOException {
+
+ SolrInputDocument document = new SolrInputDocument();
+ document.addField("id", documentId);
+ document.addField("name", itemName);
+ document.addField("price", itemPrice);
+ solrClient.add(document);
+ solrClient.commit();
+ }
+
+ public void deleteSolrDocument(String documentId) throws SolrServerException, IOException {
+
+ solrClient.deleteById(documentId);
+ solrClient.commit();
+ }
+
+ protected HttpSolrClient getSolrClient() {
+ return solrClient;
+ }
+
+ protected void setSolrClient(HttpSolrClient solrClient) {
+ this.solrClient = solrClient;
+ }
+}
diff --git a/spring-data-solr/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java
similarity index 64%
rename from spring-data-solr/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java
rename to apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java
index ce90ccaf16..22f9eae8ee 100644
--- a/spring-data-solr/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java
+++ b/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaIntegrationTest.java
@@ -6,32 +6,21 @@ import java.io.IOException;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.HttpSolrClient;
-import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.common.SolrInputDocument;
import org.junit.Before;
import org.junit.Test;
public class SolrJavaIntegrationTest {
- private HttpSolrClient solr;
- private SolrInputDocument document;
+ private SolrJavaIntegration solrJavaIntegration;
@Before
public void setUp() throws Exception {
- solr = new HttpSolrClient("http://localhost:8983/solr/bigboxstore");
- solr.setParser(new XMLResponseParser());
-
- document = new SolrInputDocument();
- document.addField("id", "123456");
- document.addField("name", "Kenmore Dishwasher");
- document.addField("price", "599.99");
- solr.add(document);
- solr.commit();
+ solrJavaIntegration = new SolrJavaIntegration("http://localhost:8983/solr/bigboxstore");
+ solrJavaIntegration.addSolrDocument("123456", "Kenmore Dishwasher", "599.99");
}
@Test
@@ -41,7 +30,7 @@ public class SolrJavaIntegrationTest {
query.set("q", "id:123456");
QueryResponse response = null;
- response = solr.query(query);
+ response = solrJavaIntegration.getSolrClient().query(query);
SolrDocumentList docList = response.getResults();
assertEquals(docList.getNumFound(), 1);
@@ -55,14 +44,13 @@ public class SolrJavaIntegrationTest {
@Test
public void whenDelete_thenVerifyDeleted() throws SolrServerException, IOException {
- solr.deleteById("123456");
- solr.commit();
+ solrJavaIntegration.deleteSolrDocument("123456");
SolrQuery query = new SolrQuery();
query.set("q", "id:123456");
QueryResponse response = null;
- response = solr.query(query);
+ response = solrJavaIntegration.getSolrClient().query(query);
SolrDocumentList docList = response.getResults();
assertEquals(docList.getNumFound(), 0);
diff --git a/apache-thrift/README.md b/apache-thrift/README.md
new file mode 100644
index 0000000000..d8b9195dcc
--- /dev/null
+++ b/apache-thrift/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Working with Apache Thrift](http://www.baeldung.com/apache-thrift)
diff --git a/apache-velocity/README.md b/apache-velocity/README.md
new file mode 100644
index 0000000000..53c67f847e
--- /dev/null
+++ b/apache-velocity/README.md
@@ -0,0 +1,3 @@
+## Relevant articles:
+
+- [Introduction to Apache Velocity](http://www.baeldung.com/apache-velocity)
diff --git a/core-java-9/README.md b/core-java-9/README.md
index 1b44239e40..53ad79e59c 100644
--- a/core-java-9/README.md
+++ b/core-java-9/README.md
@@ -6,3 +6,5 @@
### Relevant Articles:
- [Java 9 Stream API Improvements](http://www.baeldung.com/java-9-stream-api)
+- [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)
+- [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors)
diff --git a/core-java/README.md b/core-java/README.md
index 341dbdf910..a34908d8ae 100644
--- a/core-java/README.md
+++ b/core-java/README.md
@@ -58,3 +58,24 @@
- [Guide to java.util.concurrent.BlockingQueue](http://www.baeldung.com/java-blocking-queue)
- [Guide to CountDownLatch in Java](http://www.baeldung.com/java-countdown-latch)
- [How to Design a Genetic Algorithm in Java](http://www.baeldung.com/java-genetic-algorithm)
+- [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map)
+- [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue)
+- [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector)
+- [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception)
+- [Guide to WeakHashMap in Java](http://www.baeldung.com/java-weakhashmap)
+- [Strategy Design Pattern in Java 8](http://www.baeldung.com/java-strategy-pattern)
+- [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams)
+- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool)
+- [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings)
+- [Spring Security – Cache Control Headers](http://www.baeldung.com/spring-security-cache-control-headers)
+- [Basic Introduction to JMX](http://www.baeldung.com/java-management-extensions)
+- [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda)
+- [Introduction to Nashorn](http://www.baeldung.com/java-nashorn)
+- [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions)
+- [Guide to the Guava BiMap](http://www.baeldung.com/guava-bimap)
+- [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream)
+- [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany)
+- [Chained Exceptions in Java](http://www.baeldung.com/java-chained-exceptions)
+- [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap)
+- [A Guide to LinkedHashMap in Java](http://www.baeldung.com/java-linked-hashmap)
+- [A Guide to TreeMap in Java](http://www.baeldung.com/java-treemap)
diff --git a/core-java/src/test/java/com/baeldung/java/map/README.md b/core-java/src/test/java/com/baeldung/java/map/README.md
deleted file mode 100644
index 0bba153763..0000000000
--- a/core-java/src/test/java/com/baeldung/java/map/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-### Relevant Articles:
-- [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap)
diff --git a/core-java/src/test/java/com/baeldung/test/comparison/DivisibilityTest.java b/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityTest.java
similarity index 74%
rename from core-java/src/test/java/com/baeldung/test/comparison/DivisibilityTest.java
rename to core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityTest.java
index 9ae13f5934..dec7dbe6aa 100644
--- a/core-java/src/test/java/com/baeldung/test/comparison/DivisibilityTest.java
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/DivisibilityTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.test.comparison;
+package com.baeldung.junit4vstestng;
import static org.junit.Assert.assertEquals;
@@ -15,7 +15,7 @@ public class DivisibilityTest {
}
@Test
- public void givenNumber_whenDivisiblebyTwo_thenCorrect() {
+ public void givenNumber_whenDivisibleByTwo_thenCorrect() {
assertEquals(number % 2, 0);
}
}
diff --git a/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedTests.java b/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedTests.java
new file mode 100644
index 0000000000..e9a9c6a07a
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/junit4vstestng/ParametrizedTests.java
@@ -0,0 +1,34 @@
+package com.baeldung.junit4vstestng;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(value = Parameterized.class)
+public class ParametrizedTests {
+
+ private int value;
+ private boolean isEven;
+
+ public ParametrizedTests(int value, boolean isEven) {
+ this.value = value;
+ this.isEven = isEven;
+ }
+
+ @Parameters
+ public static Collection