From 3fa51bdb96f85b0365e4ae4a114e98e9ba49db77 Mon Sep 17 00:00:00 2001 From: kalle Date: Sun, 26 Jun 2011 22:11:28 +0200 Subject: [PATCH] strict and slack mode introduced. --- changelog.txt | 15 ++- json-path-assert/pom.xml | 6 ++ .../com/jayway/jsonassert/JsonAssert.java | 57 +++++++++--- .../com/jayway/jsonassert/JsonAssertTest.java | 5 +- json-path/pom.xml | 18 +++- .../java/com/jayway/jsonpath/JsonPath.java | 92 ++++++------------- .../jsonpath/filter/JsonPathFilterChain.java | 1 - .../jsonpath/filter/ListEvalFilter.java | 2 +- .../jsonpath/filter/ListFrontFilter.java | 2 +- .../jsonpath/filter/ListIndexFilter.java | 2 +- .../jsonpath/filter/ListPropertyFilter.java | 2 +- .../jsonpath/filter/PropertyFilter.java | 2 +- .../jsonpath/filter/TraverseFilter.java | 2 +- .../filter/WildcardPropertyFilter.java | 2 +- .../com/jayway/jsonpath/JsonPathTest.java | 16 +++- .../java/com/jayway/jsonpath/ParserTest.java | 51 ++++++++++ pom.xml | 17 +++- 17 files changed, 194 insertions(+), 98 deletions(-) create mode 100644 json-path/src/test/java/com/jayway/jsonpath/ParserTest.java diff --git a/changelog.txt b/changelog.txt index 159600a2..448c10d4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,10 +1,8 @@ ------------------------------------------ -0.5.2 +0.5.5 ------------------------------------------ - -- Fixed issue that path was never considered definite if containing a ':' -- Bracket notation is now first class citizen $.foo.bar == $.['foo'].['bar'] -- Added JsonAsserter.assertNotDefined(String path) to allow checks for negative existence of a path +- Replaced com.googlecode.json-simple with net.minidev.json-smart +- Introduced different parse modes, JsonPath.SLACK_MODE and JsonPath.STRICT_MODE (the slack mode lets you use single quotes or even no quotes at all) ------------------------------------------ 0.5.3 @@ -12,3 +10,10 @@ - Major refactoring - JsonPath does not always produce a List as response +------------------------------------------ +0.5.2 +------------------------------------------ + +- Fixed issue that path was never considered definite if containing a ':' +- Bracket notation is now first class citizen $.foo.bar == $.['foo'].['bar'] +- Added JsonAsserter.assertNotDefined(String path) to allow checks for negative existence of a path diff --git a/json-path-assert/pom.xml b/json-path-assert/pom.xml index 0351736a..b51256cd 100644 --- a/json-path-assert/pom.xml +++ b/json-path-assert/pom.xml @@ -39,10 +39,16 @@ test + + + net.minidev + json-smart + org.hamcrest diff --git a/json-path-assert/src/main/java/com/jayway/jsonassert/JsonAssert.java b/json-path-assert/src/main/java/com/jayway/jsonassert/JsonAssert.java index 19999fe8..d608e2e9 100644 --- a/json-path-assert/src/main/java/com/jayway/jsonassert/JsonAssert.java +++ b/json-path-assert/src/main/java/com/jayway/jsonassert/JsonAssert.java @@ -3,13 +3,10 @@ package com.jayway.jsonassert; import com.jayway.jsonassert.impl.JsonAsserterImpl; import com.jayway.jsonassert.impl.matcher.*; +import net.minidev.json.parser.JSONParser; import org.hamcrest.Matcher; -import org.json.simple.parser.JSONParser; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; +import java.io.*; import java.text.ParseException; import java.util.Collection; import java.util.Map; @@ -21,7 +18,23 @@ import java.util.Map; */ public class JsonAssert { - private static final JSONParser JSON_PARSER = new JSONParser(); + private static JSONParser JSON_PARSER = new JSONParser(); + + public final static int STRICT_MODE = 0; + public final static int SLACK_MODE = -1; + + private static int mode = SLACK_MODE; + + public static void setMode(int mode) { + if (mode != JsonAssert.mode) { + JsonAssert.mode = mode; + JSON_PARSER = new JSONParser(JsonAssert.mode); + } + } + + public static int getMode() { + return mode; + } /** * Creates a JSONAsserter @@ -33,8 +46,10 @@ public class JsonAssert { public static JsonAsserter with(String json) throws ParseException { try { return new JsonAsserterImpl(JSON_PARSER.parse(json)); - } catch (org.json.simple.parser.ParseException e) { + } catch (net.minidev.json.parser.ParseException e) { throw new ParseException(json, e.getPosition()); + } catch (IOException e) { + throw new RuntimeException(e); } } @@ -47,11 +62,9 @@ public class JsonAssert { */ public static JsonAsserter with(Reader reader) throws ParseException, IOException { try { - return new JsonAsserterImpl(JSON_PARSER.parse(reader)); - } catch (org.json.simple.parser.ParseException e) { + return new JsonAsserterImpl(JSON_PARSER.parse(convertReaderToString(reader))); + } catch (net.minidev.json.parser.ParseException e) { throw new ParseException(e.toString(), e.getPosition()); - } finally { - reader.close(); } } @@ -85,4 +98,26 @@ public class JsonAssert { return new IsEmptyCollection(); } + private static String convertReaderToString(Reader reader) + throws IOException { + + if (reader != null) { + Writer writer = new StringWriter(); + + char[] buffer = new char[1024]; + try { + int n; + while ((n = reader.read(buffer)) != -1) { + writer.write(buffer, 0, n); + } + } finally { + reader.close(); + } + return writer.toString(); + } else { + return ""; + } + } + + } diff --git a/json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java b/json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java index d22485e8..33256ae7 100644 --- a/json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java +++ b/json-path-assert/src/test/java/com/jayway/jsonassert/JsonAssertTest.java @@ -1,7 +1,6 @@ package com.jayway.jsonassert; import org.hamcrest.Matchers; -import org.json.simple.parser.JSONParser; import org.junit.Test; import java.io.InputStream; @@ -55,7 +54,7 @@ public class JsonAssertTest { @Test public void links_document() throws Exception { - with(getResourceAsStream("links.json")).assertEquals("count", 2L) + with(getResourceAsStream("links.json")).assertEquals("count", 2) .assertThat("links.gc:this.href", endsWith("?pageNumber=1&pageSize=2")) .assertNotDefined("links.gc:prev") .assertNotDefined("links.gc:next") @@ -146,7 +145,7 @@ public class JsonAssertTest { @Test public void path_including_wildcard_path_followed_by_another_path_concatenates_results_to_list() throws Exception { - with(getResourceAsStream("lotto.json")).assertThat("lotto.winners[*].winnerId", hasItems(23L, 54L)); + with(getResourceAsStream("lotto.json")).assertThat("lotto.winners[*].winnerId", hasItems(23, 54)); } diff --git a/json-path/pom.xml b/json-path/pom.xml index 989ab45c..667617bd 100644 --- a/json-path/pom.xml +++ b/json-path/pom.xml @@ -14,7 +14,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + 4.0.0 com.jayway.jsonpath @@ -28,14 +29,29 @@ json-path http://maven.apache.org + + + net.minidev + json-smart + + commons-lang commons-lang + + + net.minidev + json-smart + 1.0.6.3 + + + diff --git a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java index e1422b69..2087653c 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java +++ b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java @@ -3,15 +3,14 @@ package com.jayway.jsonpath; import com.jayway.jsonpath.filter.FilterOutput; import com.jayway.jsonpath.filter.JsonPathFilterChain; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; +import net.minidev.json.parser.JSONParser; +import net.minidev.json.parser.ParseException; -import java.util.List; -import java.util.logging.Level; +import java.io.IOException; import java.util.logging.Logger; -import static java.lang.String.format; - /** * User: kalle stenflo * Date: 2/2/11 @@ -76,12 +75,29 @@ import static java.lang.String.format; */ public class JsonPath { + public final static int STRICT_MODE = 0; + public final static int SLACK_MODE = -1; + + private static int mode = SLACK_MODE; + private final static Logger log = Logger.getLogger(JsonPath.class.getName()); - private static JSONParser JSON_PARSER = new JSONParser(); + private static JSONParser JSON_PARSER = new JSONParser(JsonPath.mode); private JsonPathFilterChain filters; + public static void setMode(int mode){ + if(mode != JsonPath.mode){ + JsonPath.mode = mode; + JSON_PARSER = new JSONParser(JsonPath.mode); + } + } + + public static int getMode(){ + return mode; + } + + /** * Creates a new JsonPath. * @@ -108,11 +124,11 @@ public class JsonPath { public T read(Object json) { FilterOutput filterOutput = filters.filter(json); - if(filterOutput == null || filterOutput.getResult() == null){ + if (filterOutput == null || filterOutput.getResult() == null) { return null; } - return (T)filterOutput.getResult(); + return (T) filterOutput.getResult(); } /** @@ -123,7 +139,7 @@ public class JsonPath { * @return list of objects matched by the given path */ public T read(String json) throws java.text.ParseException { - return (T)read(parse(json)); + return (T) read(parse(json)); } /** @@ -145,7 +161,7 @@ public class JsonPath { * @return list of objects matched by the given path */ public static T read(String json, String jsonPath) throws java.text.ParseException { - return (T)compile(jsonPath).read(json); + return (T) compile(jsonPath).read(json); } /** @@ -157,65 +173,17 @@ public class JsonPath { * @return list of objects matched by the given path */ public static T read(Object json, String jsonPath) { - return (T)compile(jsonPath).read(json); + return (T) compile(jsonPath).read(json); } - /** - * Creates a new JsonPath and applies it to the provided Json object. Note this method - * will throw an exception if the provided path returns more than one object. This method - * can be used with paths that are not definite but a warning will be generated. - * - * @param json a json object - * @param jsonPath the json path - * @param - * @return the object matched by the given path - */ - -// public static T readOne(Object json, String jsonPath) { -// Object result = compile(jsonPath).read(json, jsonPath); -// -// if (log.isLoggable(Level.WARNING)) { -// if (!PathUtil.isPathDefinite(jsonPath)) { -// log.warning("Using readOne() on a not definite json path may give incorrect results. Path : " + jsonPath); -// } -// } -// -// return (T)result; -// -// /* -// if(result instanceof List){ -// if (result.size() > 1) { -// throw new RuntimeException(format("Expected one result when reading path: %s but was: ", jsonPath, result.size())); -// } -// else if (result.isEmpty()){ -// return null; -// } -// return (T) result.get(0); -// } -// */ -// } - - - /** - * Creates a new JsonPath and applies it to the provided Json object. Note this method - * will throw an exception if the provided path returns more than one object. This method - * can be used with paths that are not definite but a warning will be generated. - * - * @param json a json string - * @param jsonPath the json path - * @param - * @return the object matched by the given path - */ -// public static T readOne(String json, String jsonPath) throws java.text.ParseException { -// return (T) readOne(parse(json), jsonPath); -// } - private static Object parse(String json) throws java.text.ParseException { try { return JSON_PARSER.parse(json); } catch (ParseException e) { throw new java.text.ParseException(json, e.getPosition()); + } catch (IOException e) { + throw new RuntimeException(e); } } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/JsonPathFilterChain.java b/json-path/src/main/java/com/jayway/jsonpath/filter/JsonPathFilterChain.java index 9ee917eb..4f183641 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/JsonPathFilterChain.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/JsonPathFilterChain.java @@ -1,7 +1,6 @@ package com.jayway.jsonpath.filter; import com.jayway.jsonpath.InvalidPathException; -import org.json.simple.JSONArray; import java.util.LinkedList; import java.util.List; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/ListEvalFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/ListEvalFilter.java index 450888d0..405d8973 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/ListEvalFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/ListEvalFilter.java @@ -2,7 +2,7 @@ package com.jayway.jsonpath.filter; import com.jayway.jsonpath.JsonUtil; import com.jayway.jsonpath.eval.ExpressionEvaluator; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.List; import java.util.Map; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/ListFrontFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/ListFrontFilter.java index 27279d8c..797e0d1f 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/ListFrontFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/ListFrontFilter.java @@ -1,6 +1,6 @@ package com.jayway.jsonpath.filter; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.LinkedList; import java.util.List; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/ListIndexFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/ListIndexFilter.java index def5f22f..18c72cc1 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/ListIndexFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/ListIndexFilter.java @@ -1,6 +1,6 @@ package com.jayway.jsonpath.filter; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.LinkedList; import java.util.List; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/ListPropertyFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/ListPropertyFilter.java index 3827caaf..33b3d4fd 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/ListPropertyFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/ListPropertyFilter.java @@ -1,7 +1,7 @@ package com.jayway.jsonpath.filter; import com.jayway.jsonpath.JsonUtil; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.List; import java.util.regex.Matcher; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/PropertyFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/PropertyFilter.java index 8cbfafe1..96f7a4fa 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/PropertyFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/PropertyFilter.java @@ -1,7 +1,7 @@ package com.jayway.jsonpath.filter; import com.jayway.jsonpath.JsonUtil; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.List; import java.util.regex.Pattern; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/TraverseFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/TraverseFilter.java index 09170e0d..c8b88a0c 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/TraverseFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/TraverseFilter.java @@ -1,7 +1,7 @@ package com.jayway.jsonpath.filter; import com.jayway.jsonpath.JsonUtil; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.List; import java.util.regex.Pattern; diff --git a/json-path/src/main/java/com/jayway/jsonpath/filter/WildcardPropertyFilter.java b/json-path/src/main/java/com/jayway/jsonpath/filter/WildcardPropertyFilter.java index 2441596e..23740456 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/filter/WildcardPropertyFilter.java +++ b/json-path/src/main/java/com/jayway/jsonpath/filter/WildcardPropertyFilter.java @@ -1,7 +1,7 @@ package com.jayway.jsonpath.filter; import com.jayway.jsonpath.JsonUtil; -import org.json.simple.JSONArray; +import net.minidev.json.JSONArray; import java.util.List; import java.util.regex.Pattern; diff --git a/json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java b/json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java index 94c4af3b..ec49585e 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/JsonPathTest.java @@ -1,15 +1,11 @@ package com.jayway.jsonpath; -import org.json.simple.parser.JSONParser; import org.junit.Test; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.List; import java.util.Map; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItems; import static org.junit.Assert.*; @@ -21,6 +17,8 @@ import static org.junit.Assert.*; */ public class JsonPathTest { + public final static String ARRAY = "[{\"value\": 1},{\"value\": 2}, {\"value\": 3},{\"value\": 4}]"; + public final static String DOCUMENT = "{ \"store\": {\n" + " \"book\": [ \n" + @@ -55,6 +53,15 @@ public class JsonPathTest { " }\n" + "}"; + + @Test + public void filter_an_array() throws Exception { + List matches = JsonPath.read(ARRAY, "$.[?(@.value = 1)]"); + + assertEquals(1, matches.size()); + System.out.println(matches); + } + @Test public void read_path_with_colon() throws Exception { @@ -72,6 +79,7 @@ public class JsonPathTest { } + @Test public void read_store_book_1() throws Exception { diff --git a/json-path/src/test/java/com/jayway/jsonpath/ParserTest.java b/json-path/src/test/java/com/jayway/jsonpath/ParserTest.java new file mode 100644 index 00000000..9400be08 --- /dev/null +++ b/json-path/src/test/java/com/jayway/jsonpath/ParserTest.java @@ -0,0 +1,51 @@ +package com.jayway.jsonpath; + +import org.junit.Test; + +import java.text.ParseException; + +import static junit.framework.Assert.assertEquals; + +/** + * Created by IntelliJ IDEA. + * User: kallestenflo + * Date: 6/25/11 + * Time: 4:16 PM + */ +public class ParserTest { + + + private final static String SINGLE_QUOTE_JSON = "{'lhs': '1.0 U.S. dollar','rhs': 6.39778892, 'error': null, 'icc': true}"; + private final static String NO_QUOTE_JSON = "{lhs: 1.0 U.S. dollar, rhs: 6.39778892, error: null, icc: true}"; + + @Test + public void default_mode_is_SLACK_MODE() throws Exception { + assertEquals(JsonPath.SLACK_MODE, JsonPath.getMode()); + } + + @Test + public void slack_mode_allows_single_quotes() throws Exception { + assertEquals(JsonPath.read(SINGLE_QUOTE_JSON, "lhs"), "1.0 U.S. dollar"); + assertEquals(JsonPath.read(SINGLE_QUOTE_JSON, "rhs"), 6.39778892D); + } + + @Test + public void slack_mode_allows_no_quotes() throws Exception { + assertEquals(JsonPath.read(NO_QUOTE_JSON, "lhs"), "1.0 U.S. dollar"); + assertEquals(JsonPath.read(NO_QUOTE_JSON, "rhs"), 6.39778892D); + } + + @Test(expected = ParseException.class) + public void strict_mode_does_not_accept_single_quotes() throws Exception { + JsonPath.setMode(JsonPath.STRICT_MODE); + JsonPath.read(SINGLE_QUOTE_JSON, "lhs"); + } + + @Test(expected = ParseException.class) + public void strict_mode_does_not_accept_no_quotes() throws Exception { + JsonPath.setMode(JsonPath.STRICT_MODE); + JsonPath.read(NO_QUOTE_JSON, "lhs"); + } + + +} diff --git a/pom.xml b/pom.xml index 64e57530..40cd4f14 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + 4.0.0 org.sonatype.oss @@ -31,7 +32,7 @@ 2011 GitHub Issue Tracking - + @@ -102,7 +103,8 @@ copy-dependencies - ${project.build.directory}/dependencies/${project.version} + ${project.build.directory}/dependencies/${project.version} + false false true @@ -152,12 +154,19 @@ - + + + + net.minidev + json-smart + 1.0.6.3 + org.hamcrest