diff --git a/json-path/.classpath b/json-path/.classpath
new file mode 100644
index 0000000000..2244ed1e21
--- /dev/null
+++ b/json-path/.classpath
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/json-path/.gitignore b/json-path/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/json-path/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/json-path/.project b/json-path/.project
new file mode 100644
index 0000000000..caa2c41711
--- /dev/null
+++ b/json-path/.project
@@ -0,0 +1,23 @@
+
+
+ json-path
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/json-path/pom.xml b/json-path/pom.xml
new file mode 100644
index 0000000000..b51f59c411
--- /dev/null
+++ b/json-path/pom.xml
@@ -0,0 +1,61 @@
+
+ 4.0.0
+ org.baeldung
+ json-path
+ 0.0.1-SNAPSHOT
+ json-path
+
+
+
+
+ com.jayway.jsonpath
+ json-path
+ ${json-path.version}
+
+
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ runtime
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+ runtime
+
+
+
+
+
+ 2.1.0
+
+
+ 2.9.2
+
+
+ 4.12
+
+
+ 1.7.14
+ 1.1.3
+
+
\ No newline at end of file
diff --git a/json-path/src/main/resources/intro_api.json b/json-path/src/main/resources/intro_api.json
new file mode 100644
index 0000000000..8a252f2971
--- /dev/null
+++ b/json-path/src/main/resources/intro_api.json
@@ -0,0 +1,57 @@
+{
+ "tool":
+ {
+ "jsonpath":
+ {
+ "creator":
+ {
+ "name": "Jayway Inc.",
+ "location":
+ [
+ "Malmo",
+ "Stockholm",
+ "Copenhagen",
+ "San Francisco",
+ "Karlskrona",
+ "Halmstad",
+ "Helsingborg"
+ ]
+ },
+
+ "current release": "2.1"
+ }
+ },
+
+ "book":
+ [
+ {
+ "title": "Beginning JSON",
+ "author": "Ben Smith",
+ "price": 49.99
+ },
+
+ {
+ "title": "JSON at Work",
+ "author": "Tom Marrs",
+ "price": 29.99
+ },
+
+ {
+ "title": "Learn JSON in a DAY",
+ "author": "Acodemy",
+ "price": 8.99
+ },
+
+ {
+ "title": "JSON: Questions and Answers",
+ "author": "George Duckett",
+ "price": 6.00
+ }
+ ],
+
+ "price range":
+ {
+ "cheap": 10.00,
+ "medium": 20.00
+ }
+}
\ No newline at end of file
diff --git a/json-path/src/main/resources/intro_user.json b/json-path/src/main/resources/intro_user.json
new file mode 100644
index 0000000000..c35914c6c4
--- /dev/null
+++ b/json-path/src/main/resources/intro_user.json
@@ -0,0 +1,46 @@
+[
+ {
+ "username": "oracle",
+ "password":
+ {
+ "current":
+ {
+ "value": "Java_SE_8",
+ "created": 1397754000000
+ },
+
+ "old":
+ [
+ {
+ "value": "Java_SE_7",
+ "created": 1312650000000
+ }
+ ]
+ }
+ },
+
+ {
+ "username": "sun",
+ "password":
+ {
+ "current":
+ {
+ "value": "Java_SE_6",
+ "created": 1168448400000
+ },
+
+ "old":
+ [
+ {
+ "value": "J2SE_5.0",
+ "created": 1099069200000
+ },
+
+ {
+ "value": "J2SE_1.4",
+ "created": 1025542800000
+ }
+ ]
+ }
+ }
+]
\ No newline at end of file
diff --git a/json-path/src/test/java/org/baeldung/jsonpath/introduction/ChangingPasswordTest.java b/json-path/src/test/java/org/baeldung/jsonpath/introduction/ChangingPasswordTest.java
new file mode 100644
index 0000000000..24f8500d3d
--- /dev/null
+++ b/json-path/src/test/java/org/baeldung/jsonpath/introduction/ChangingPasswordTest.java
@@ -0,0 +1,85 @@
+package org.baeldung.jsonpath.introduction;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+import org.joda.time.DateTime;
+import org.joda.time.Years;
+
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.Option;
+
+public class ChangingPasswordTest {
+
+ enum Result {
+ SUCCESS, FAILURE
+ }
+
+ InputStream jsonValueInputStream = this.getClass().getClassLoader().getResourceAsStream("intro_user.json");
+ String jsonDataSourceString = new Scanner(jsonValueInputStream, "UTF-8").useDelimiter("\\Z").next();
+
+ @Test
+ public void givenUseCase_whenChangingPasswordOfNonExistentUser_thenFail() {
+ String failedRequestBody = "{\"username\":\"jayway\", \"new_password\":\"JsonPath\"}";
+ Result result = changingPasswordHelper(failedRequestBody);
+
+ assertEquals(Result.FAILURE, result);
+ }
+
+ @Test
+ public void givenUseCase_whenChangingToUnusedPassword_thenSucceed() {
+ String successfulRequestBody = "{\"username\":\"oracle\", \"new_password\":\"Java_SE_9\"}";
+ Result result = changingPasswordHelper(successfulRequestBody);
+
+ assertEquals(Result.SUCCESS, result);
+ }
+
+ @Test
+ public void givenUseCase_whenChangingToRecentlyUsedPassword_thenFail() {
+ String failedRequestBody = "{\"username\":\"oracle\", \"new_password\":\"Java_SE_7\"}";
+ Result result = changingPasswordHelper(failedRequestBody);
+
+ assertEquals(Result.FAILURE, result);
+ }
+
+ @Test
+ public void givenUseCase_whenChangingToLongTimeAgoPassword_thenSucceed() {
+ String successfulRequestBody = "{\"username\":\"sun\", \"new_password\":\"J2SE_5.0\"}";
+ Result result = changingPasswordHelper(successfulRequestBody);
+
+ assertEquals(Result.SUCCESS, result);
+ }
+
+ private Result changingPasswordHelper(String requestBody) {
+ DocumentContext requestContext = JsonPath.parse(requestBody);
+ String extractedUsername = requestContext.read("$['username']");
+ String extractedPassword = requestContext.read("$['new_password']");
+
+ DocumentContext jsonContext = JsonPath.parse(jsonDataSourceString);
+ List dataSourceUsername = jsonContext.read("$[?(@.username == '" + extractedUsername + "')]");
+ if (dataSourceUsername.size() == 0)
+ return Result.FAILURE;
+
+ Configuration pathConfiguration = Configuration.builder().options(Option.AS_PATH_LIST).build();
+ List pathToCurrentUser = JsonPath.using(pathConfiguration).parse(jsonDataSourceString).read("$[?(@.username == '" + extractedUsername + "')]");
+ List passwordCreatedTimeList = jsonContext.read(pathToCurrentUser.get(0) + "['password']['old'][?(@.value == '" + extractedPassword + "')]['created']");
+ if (passwordCreatedTimeList.size() == 0)
+ return Result.SUCCESS;
+
+ Long[] passwordCreatedTimeArray = (passwordCreatedTimeList.toArray(new Long[passwordCreatedTimeList.size()]));
+ Arrays.sort(passwordCreatedTimeArray);
+ DateTime oldDate = new DateTime(passwordCreatedTimeArray[passwordCreatedTimeArray.length - 1]);
+ if (Years.yearsBetween(oldDate, new DateTime()).getYears() <= 10)
+ return Result.FAILURE;
+
+ return Result.SUCCESS;
+ }
+}
diff --git a/json-path/src/test/java/org/baeldung/jsonpath/introduction/LoggingInTest.java b/json-path/src/test/java/org/baeldung/jsonpath/introduction/LoggingInTest.java
new file mode 100644
index 0000000000..1ab7dad88e
--- /dev/null
+++ b/json-path/src/test/java/org/baeldung/jsonpath/introduction/LoggingInTest.java
@@ -0,0 +1,50 @@
+package org.baeldung.jsonpath.introduction;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Scanner;
+
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.JsonPath;
+
+public class LoggingInTest {
+
+ enum Result {
+ SUCCESS, FAILURE
+ }
+
+ InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("intro_user.json");
+ String jsonDataSourceString = new Scanner(jsonInputStream, "UTF-8").useDelimiter("\\Z").next();
+
+ @Test
+ public void givenUseCase_whenLoggingInWithCorrectUserData_thenSucceed() {
+ String correctRequestBody = "{\"username\":\"sun\", \"password\":\"Java_SE_6\"}";
+ Result result = loggingInHelper(correctRequestBody);
+
+ assertEquals(Result.SUCCESS, result);
+ }
+
+ @Test
+ public void givenUseCase_whenLoggingInWithIncorrectUserData_thenFail() {
+ String incorrectRequestBody = "{\"username\":\"oracle\", \"password\":\"Java_SE_9\"}";
+ Result result = loggingInHelper(incorrectRequestBody);
+
+ assertEquals(Result.FAILURE, result);
+ }
+
+ private Result loggingInHelper(String requestBody) {
+ DocumentContext requestContext = JsonPath.parse(requestBody);
+ String extractedUsername = requestContext.read("$['username']");
+ String extractedPassword = requestContext.read("$['password']");
+ List list = JsonPath.parse(jsonDataSourceString).read("$[?(@.username == '" + extractedUsername + "' && @.password.current.value == '" + extractedPassword + "')]");
+
+ if (list.size() == 0)
+ return Result.FAILURE;
+ return Result.SUCCESS;
+ }
+
+}
diff --git a/json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java b/json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java
new file mode 100644
index 0000000000..9347a7f754
--- /dev/null
+++ b/json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java
@@ -0,0 +1,71 @@
+package org.baeldung.jsonpath.introduction;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+
+import com.jayway.jsonpath.Criteria;
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.Filter;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.Predicate;
+
+public class OperationTest {
+ InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("intro_api.json");
+ String jsonDataSourceString = new Scanner(jsonInputStream, "UTF-8").useDelimiter("\\Z").next();
+
+ @Test
+ public void givenJsonPathWithoutPredicates_whenReading_thenCorrect() {
+ String jsonpathCreatorNamePath = "$['tool']['jsonpath']['creator']['name']";
+ String jsonpathCreatorLocationPath = "$['tool']['jsonpath']['creator']['location'][*]";
+
+ DocumentContext jsonContext = JsonPath.parse(jsonDataSourceString);
+ String jsonpathCreatorName = jsonContext.read(jsonpathCreatorNamePath);
+ List jsonpathCreatorLocation = jsonContext.read(jsonpathCreatorLocationPath);
+
+ assertEquals("Jayway Inc.", jsonpathCreatorName);
+ assertThat(jsonpathCreatorLocation.toString(), containsString("Malmo"));
+ assertThat(jsonpathCreatorLocation.toString(), containsString("San Francisco"));
+ assertThat(jsonpathCreatorLocation.toString(), containsString("Helsingborg"));
+ }
+
+ @Test
+ public void givenJsonPathWithFilterPredicate_whenReading_thenCorrect() {
+ Filter expensiveFilter = Filter.filter(Criteria.where("price").gt(20.00));
+ List