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 6e14afec..056b927f 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
@@ -1,15 +1,16 @@
package com.jayway.jsonpath;
-import com.jayway.jsonpath.filter.FilterOutput;
-import com.jayway.jsonpath.filter.JsonPathFilterChain;
-import net.minidev.json.JSONArray;
-import net.minidev.json.JSONObject;
+import com.jayway.jsonpath.reader.PathToken;
+import com.jayway.jsonpath.reader.PathTokenizer;
import net.minidev.json.parser.JSONParser;
import net.minidev.json.parser.ParseException;
import java.io.IOException;
+import java.util.List;
+import java.util.Map;
import java.util.logging.Logger;
+import java.util.regex.Pattern;
/**
* User: kalle stenflo
@@ -84,16 +85,18 @@ public class JsonPath {
private static JSONParser JSON_PARSER = new JSONParser(JsonPath.mode);
- private JsonPathFilterChain filters;
+ private static Pattern DEFINITE_PATH_PATTERN = Pattern.compile(".*(\\.\\.|\\*|\\[[\\\\/]|\\?|,|:\\s?\\]|\\[\\s?:|>|\\(|<|=|\\+).*");
- public static void setMode(int mode){
- if(mode != JsonPath.mode){
+ private PathTokenizer tokenizer;
+
+ public static void setMode(int mode) {
+ if (mode != JsonPath.mode) {
JsonPath.mode = mode;
JSON_PARSER = new JSONParser(JsonPath.mode);
}
}
- public static int getMode(){
+ public static int getMode() {
return mode;
}
@@ -111,24 +114,71 @@ public class JsonPath {
throw new InvalidPathException("Invalid path");
}
- this.filters = new JsonPathFilterChain(PathUtil.splitPath(jsonPath));
+ this.tokenizer = new PathTokenizer(jsonPath);
+ //this.filters = new JsonPathFilterChain(PathUtil.splitPath(jsonPath));
+ }
+
+ public String getPath() {
+ return this.tokenizer.getPath();
}
/**
- * Applies this json path to the provided object
+ * Checks if a path points to a single item or if it potentially returns multiple items
+ *
+ * a path is considered not definite if it contains a scan fragment ".."
+ * or an array position fragment that is not based on a single index
+ *
+ *
+ * definite path examples are:
+ *
+ * $store.book
+ * $store.book[1].title
+ *
+ * not definite path examples are:
+ *
+ * $..book
+ * $.store.book[1,2]
+ * $.store.book[?(@.category = 'fiction')]
*
- * @param json a json Object
+ * @return true if path is definite (points to single item)
+ */
+ public boolean isPathDefinite() {
+ //return !getPath().replaceAll("\"[^\"\\\\\\n\r]*\"", "").matches(".*(\\.\\.|\\*|\\[[\\\\/]|\\?|,|:\\s?\\]|\\[\\s?:|>|\\(|<|=|\\+).*");
+
+ String preparedPath = getPath().replaceAll("\"[^\"\\\\\\n\r]*\"", "");
+
+ return !DEFINITE_PATH_PATTERN.matcher(preparedPath).matches();
+
+ }
+
+ /**
+ * Applies this container path to the provided object
+ *
+ * @param container a container Object
* @param
* @return list of objects matched by the given path
*/
- public T read(Object json) {
- FilterOutput filterOutput = filters.filter(json);
+ public T read(Object container) {
+
+ if(!(container instanceof Map) && !(container instanceof List) ){
+ throw new IllegalArgumentException("Invalid container object");
+ }
+
+ Object result = container;
+
+ for (PathToken pathToken : tokenizer) {
+ result = pathToken.filter(result);
+ }
+ return (T)result;
+ /*
+ FilterOutput filterOutput = filters.filter(container);
if (filterOutput == null || filterOutput.getResult() == null) {
return null;
}
return (T) filterOutput.getResult();
+ */
}
/**
diff --git a/json-path/src/main/java/com/jayway/jsonpath/reader/PathTokenizer.java b/json-path/src/main/java/com/jayway/jsonpath/reader/PathTokenizer.java
index e3f97c07..f386f96c 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/reader/PathTokenizer.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/reader/PathTokenizer.java
@@ -14,6 +14,7 @@ import java.util.List;
*/
public class PathTokenizer implements Iterable {
+ private String path;
private char[] pathChars;
private int index = 0;
private List pathTokens = new LinkedList();
@@ -23,13 +24,18 @@ public class PathTokenizer implements Iterable {
if (!jsonPath.startsWith("$") && !jsonPath.startsWith("$[")) {
jsonPath = "$." + jsonPath;
}
- pathChars = jsonPath.toCharArray();
+ this.path = jsonPath;
+ this.pathChars = path.toCharArray();
for (String pathFragment : splitPath()) {
pathTokens.add(new PathToken(pathFragment));
}
}
+ public String getPath() {
+ return path;
+ }
+
public Iterator iterator() {
return pathTokens.iterator();
}
diff --git a/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayEvalFilter.java b/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayEvalFilter.java
index a6da0b48..781ad048 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayEvalFilter.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayEvalFilter.java
@@ -34,6 +34,8 @@ public class ArrayEvalFilter extends Filter {
ConditionStatement conditionStatement = createConditionStatement(trimmedCondition);
+
+
for (Object item : src) {
if (isMatch(item, conditionStatement)) {
result.add(item);
@@ -83,6 +85,10 @@ public class ArrayEvalFilter extends Filter {
this.field = field;
this.operator = operator;
this.expected = expected;
+
+ if(this.expected.startsWith("'")){
+ this.expected = trim(this.expected, 1, 1);
+ }
}
public String getField() {
diff --git a/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayIndexFilter.java b/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayIndexFilter.java
index a51beec5..3d3bb00d 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayIndexFilter.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/reader/filter/ArrayIndexFilter.java
@@ -22,6 +22,13 @@ public class ArrayIndexFilter extends Filter {
String trimmedCondition = trim(condition, 1, 1);
+ if(trimmedCondition.contains("@.length")){
+ trimmedCondition = trim(trimmedCondition, 1, 1);
+ trimmedCondition = trimmedCondition.replace("@.length", "");
+ trimmedCondition = trimmedCondition + ":";
+ }
+
+
if (trimmedCondition.startsWith(":")) {
trimmedCondition = trim(trimmedCondition, 1, 0);
int get = Integer.parseInt(trimmedCondition);
@@ -34,6 +41,7 @@ public class ArrayIndexFilter extends Filter {
trimmedCondition = trim(trimmedCondition, 1, 1);
int get = Integer.parseInt(trimmedCondition);
return src.get(src.size() - get);
+
} else {
String[] indexArr = trimmedCondition.split(",");
diff --git a/json-path/src/main/java/com/jayway/jsonpath/reader/filter/FieldFilter.java b/json-path/src/main/java/com/jayway/jsonpath/reader/filter/FieldFilter.java
index 79a9579c..de8f4d87 100644
--- a/json-path/src/main/java/com/jayway/jsonpath/reader/filter/FieldFilter.java
+++ b/json-path/src/main/java/com/jayway/jsonpath/reader/filter/FieldFilter.java
@@ -17,10 +17,20 @@ public class FieldFilter extends Filter {
}
public Object filter(Object obj) {
- if(isList(obj)){
+ if (isList(obj)) {
List