diff --git a/json-path/build.gradle b/json-path/build.gradle index 3aec3088..812eac64 100644 --- a/json-path/build.gradle +++ b/json-path/build.gradle @@ -6,7 +6,7 @@ jar { baseName 'json-path' manifest { attributes 'Implementation-Title': 'json-path', 'Implementation-Version': version - instruction 'Import-Package', 'org.json.*;resolution:=optional', 'com.google.gson.*;resolution:=optional', 'com.fasterxml.jackson.*;resolution:=optional', 'net.minidev.json.*;resolution:=optional', 'org.apache.tapestry5.json.*;resolution:=optional', 'org.codehaus.jettison.*;resolution:=optional', '*' + instruction 'Import-Package', 'org.json.*;resolution:=optional', 'com.google.gson.*;resolution:=optional', 'com.fasterxml.jackson.*;resolution:=optional', 'org.apache.tapestry5.json.*;resolution:=optional', 'org.codehaus.jettison.*;resolution:=optional', '*' } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java index 3f3914e4..08d257c4 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java @@ -11,6 +11,10 @@ import com.jayway.jsonpath.internal.Utils; import com.jayway.jsonpath.internal.path.PathCompiler; import com.jayway.jsonpath.internal.path.PredicateContextImpl; import com.jayway.jsonpath.spi.json.JsonProvider; + +import net.minidev.json.parser.JSONParser; +import net.minidev.json.parser.ParseException; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -153,7 +157,7 @@ public abstract class ValueNode { char c1 = str.charAt(str.length() - 1); if ((c0 == '[' && c1 == ']') || (c0 == '{' && c1 == '}')){ try { - Configuration.defaultConfiguration().jsonProvider().parse(str); + new JSONParser(JSONParser.MODE_PERMISSIVE).parse(str); return true; } catch(Exception e){ return false; @@ -314,11 +318,11 @@ public abstract class ValueNode { @Override public Class type(Predicate.PredicateContext ctx) { - if(ctx.configuration().jsonProvider().isArray(parse(ctx))) return List.class; - else if(ctx.configuration().jsonProvider().isMap(parse(ctx))) return Map.class; - else if(ctx.configuration().jsonProvider().unwrap(parse(ctx)) instanceof Number) return Number.class; - else if(ctx.configuration().jsonProvider().unwrap(parse(ctx)) instanceof String) return String.class; - else if(ctx.configuration().jsonProvider().unwrap(parse(ctx)) instanceof Boolean) return Boolean.class; + if(isArray(ctx)) return List.class; + else if(isMap(ctx)) return Map.class; + else if(parse(ctx) instanceof Number) return Number.class; + else if(parse(ctx) instanceof String) return String.class; + else if(parse(ctx) instanceof Boolean) return Boolean.class; else return Void.class; } @@ -334,16 +338,16 @@ public abstract class ValueNode { if(!isArray(ctx)){ return UNDEFINED; } else { - Collection nodes = new ArrayList(); - for (Object value : ctx.configuration().jsonProvider().toIterable(parse(ctx))) { - nodes.add(value); - } - return new ValueListNode(nodes); + return new ValueListNode(Collections.unmodifiableList((List) parse(ctx))); } } public Object parse(Predicate.PredicateContext ctx){ - return parsed ? json : ctx.configuration().jsonProvider().parse(json.toString()); + try { + return parsed ? json : new JSONParser(JSONParser.MODE_PERMISSIVE).parse(json.toString()); + } catch (ParseException e) { + throw new IllegalArgumentException(e); + } } public boolean isParsed() { @@ -355,19 +359,20 @@ public abstract class ValueNode { } public boolean isArray(Predicate.PredicateContext ctx) { - return ctx.configuration().jsonProvider().isArray(parse(ctx)); + return parse(ctx) instanceof List; } public boolean isMap(Predicate.PredicateContext ctx) { - return ctx.configuration().jsonProvider().isArray(parse(ctx)); + return parse(ctx) instanceof Map; } public int length(Predicate.PredicateContext ctx) { - return isArray(ctx) ? ctx.configuration().jsonProvider().length(parse(ctx)) : -1; + return isArray(ctx) ? ((List) parse(ctx)).size() : -1; } public boolean isEmpty(Predicate.PredicateContext ctx) { - if(isArray(ctx) || isMap(ctx)) return ctx.configuration().jsonProvider().length(parse(ctx)) == 0; + if (isArray(ctx)) return ((List) parse(ctx)).size() == 0; + else if (isMap(ctx)) return ((Map) parse(ctx)).size() == 0; else if((parse(ctx) instanceof String)) return ((String)parse(ctx)).length() == 0; return true; } diff --git a/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java b/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java index 7799c9d7..ef79e22a 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/JacksonTest.java @@ -45,4 +45,14 @@ public class JacksonTest extends BaseTest { assertThat(date).isEqualTo(now); } + @Test + // https://github.com/jayway/JsonPath/issues/275 + public void single_quotes_work_with_in_filter() { + final String jsonArray = "[{\"foo\": \"bar\"}, {\"foo\": \"baz\"}]"; + final Object readFromSingleQuote = JsonPath.using(JACKSON_CONFIGURATION).parse(jsonArray).read("$.[?(@.foo in ['bar'])].foo"); + final Object readFromDoubleQuote = JsonPath.using(JACKSON_CONFIGURATION).parse(jsonArray).read("$.[?(@.foo in [\"bar\"])].foo"); + assertThat(readFromSingleQuote).isEqualTo(readFromDoubleQuote); + + } + } diff --git a/json-path/src/test/java/com/jayway/jsonpath/ProviderInTest.java b/json-path/src/test/java/com/jayway/jsonpath/ProviderInTest.java index 0508539c..ca9bd716 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/ProviderInTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/ProviderInTest.java @@ -12,9 +12,7 @@ import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; import com.jayway.jsonpath.spi.mapper.JsonOrgMappingProvider; import com.jayway.jsonpath.spi.mapper.JsonSmartMappingProvider; import org.assertj.core.util.Lists; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import java.util.List; @@ -32,9 +30,6 @@ public class ProviderInTest { private final String SINGLE_QUOTES_IN_FILTER = String.format(IN_FILTER, SINGLE_QUOTES); - @Rule - public final ExpectedException exception = ExpectedException.none(); - @Test public void testJsonPathQuotesJackson() throws Exception { final Configuration jackson = Configuration.builder().jsonProvider(new JacksonJsonProvider()).mappingProvider(new JacksonMappingProvider()).build(); @@ -49,8 +44,8 @@ public class ProviderInTest { final List doubleQuoteInResult = ctx.read(DOUBLE_QUOTES_IN_FILTER); assertEquals(doubleQuoteInResult, doubleQuoteEqualsResult); - exception.expect(InvalidJsonException.class); - ctx.read(SINGLE_QUOTES_IN_FILTER); + final List singleQuoteInResult = ctx.read(SINGLE_QUOTES_IN_FILTER); + assertEquals(doubleQuoteInResult, singleQuoteInResult); } @@ -68,8 +63,8 @@ public class ProviderInTest { final ArrayNode doubleQuoteInResult = ctx.read(DOUBLE_QUOTES_IN_FILTER); assertEquals(doubleQuoteInResult, doubleQuoteEqualsResult); - exception.expect(InvalidJsonException.class); - ctx.read(SINGLE_QUOTES_IN_FILTER); + final ArrayNode singleQuoteInResult = ctx.read(SINGLE_QUOTES_IN_FILTER); + assertEquals(doubleQuoteInResult, singleQuoteInResult); } @Test