Browse Source

Merge pull request #110 from jochenberger/improvements

Some small improvements
pull/91/merge
kallestenflo 9 years ago
parent
commit
09977aa745
  1. 50
      json-path/src/main/java/com/jayway/jsonpath/internal/PathCompiler.java
  2. 36
      json-path/src/main/java/com/jayway/jsonpath/internal/Utils.java
  3. 4
      json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java

50
json-path/src/main/java/com/jayway/jsonpath/internal/PathCompiler.java

@ -50,38 +50,38 @@ public class PathCompiler {
private static final Cache cache = new Cache(200); private static final Cache cache = new Cache(200);
public static Path compile(String path, Predicate... filters) { public static Path compile(final String path, final Predicate... filters) {
notEmpty(path, "Path may not be null empty"); notEmpty(path, "Path may not be null empty");
try { try {
path = path.trim(); String trimmedPath = path.trim();
if (path.endsWith("..")) { if (trimmedPath.endsWith("..")) {
throw new InvalidPathException("A path can not end with a scan."); throw new InvalidPathException("A path can not end with a scan.");
} }
LinkedList<Predicate> filterList = new LinkedList<Predicate>(asList(filters)); LinkedList<Predicate> filterList = new LinkedList<Predicate>(asList(filters));
if (path.charAt(0) != '$' && path.charAt(0) != '@') { if (trimmedPath.charAt(0) != '$' && trimmedPath.charAt(0) != '@') {
path = "$." + path; trimmedPath = Utils.concat("$.", trimmedPath);
} }
boolean isRootPath = (path.charAt(0) == '$'); boolean isRootPath = (trimmedPath.charAt(0) == '$');
if (path.charAt(0) == '@') { if (trimmedPath.charAt(0) == '@') {
path = "$" + path.substring(1); trimmedPath = Utils.concat("$", trimmedPath.substring(1));
} }
if (path.length() > 1 && if (trimmedPath.length() > 1 &&
path.charAt(1) != '.' && trimmedPath.charAt(1) != '.' &&
path.charAt(1) != '[') { trimmedPath.charAt(1) != '[') {
throw new InvalidPathException("Invalid path " + path); throw new InvalidPathException("Invalid path " + trimmedPath);
} }
String cacheKey = path + isRootPath + filterList.toString(); String cacheKey = Utils.concat(trimmedPath, Boolean.toString(isRootPath), filterList.toString());
Path p = cache.get(cacheKey); Path p = cache.get(cacheKey);
if (p != null) { if (p != null) {
if (logger.isDebugEnabled()) logger.debug("Using cached path: " + cacheKey); if (logger.isDebugEnabled()) logger.debug("Using cached path: {}", cacheKey);
return p; return p;
} }
@ -93,7 +93,7 @@ public class PathCompiler {
String fragment = ""; String fragment = "";
do { do {
char current = path.charAt(i); char current = trimmedPath.charAt(i);
switch (current) { switch (current) {
case SPACE: case SPACE:
@ -103,27 +103,27 @@ public class PathCompiler {
i++; i++;
break; break;
case BRACKET_OPEN: case BRACKET_OPEN:
positions = fastForwardUntilClosed(path, i); positions = fastForwardUntilClosed(trimmedPath, i);
fragment = path.substring(i, i + positions); fragment = trimmedPath.substring(i, i + positions);
i += positions; i += positions;
break; break;
case PERIOD: case PERIOD:
i++; i++;
if ( i < path.length() && path.charAt(i) == PERIOD) { if ( i < trimmedPath.length() && trimmedPath.charAt(i) == PERIOD) {
//This is a deep scan //This is a deep scan
fragment = ".."; fragment = "..";
i++; i++;
} else { } else {
positions = fastForward(path, i); positions = fastForward(trimmedPath, i);
if (positions == 0) { if (positions == 0) {
continue; continue;
} else if (positions == 1 && path.charAt(i) == '*') { } else if (positions == 1 && trimmedPath.charAt(i) == '*') {
fragment = new String("[*]"); fragment = new String("[*]");
} else { } else {
assertValidFieldChars(path, i, positions); assertValidFieldChars(trimmedPath, i, positions);
fragment = PROPERTY_OPEN + path.substring(i, i + positions) + PROPERTY_CLOSE; fragment = Utils.concat(PROPERTY_OPEN, trimmedPath.substring(i, i + positions), PROPERTY_CLOSE);
} }
i += positions; i += positions;
} }
@ -133,9 +133,9 @@ public class PathCompiler {
i++; i++;
break; break;
default: default:
positions = fastForward(path, i); positions = fastForward(trimmedPath, i);
fragment = PROPERTY_OPEN + path.substring(i, i + positions) + PROPERTY_CLOSE; fragment = Utils.concat(PROPERTY_OPEN, trimmedPath.substring(i, i + positions), PROPERTY_CLOSE);
i += positions; i += positions;
break; break;
} }
@ -145,7 +145,7 @@ public class PathCompiler {
root.append(PathComponentAnalyzer.analyze(fragment, filterList)); root.append(PathComponentAnalyzer.analyze(fragment, filterList));
} }
} while (i < path.length()); } while (i < trimmedPath.length());
Path pa = new CompiledPath(root, isRootPath); Path pa = new CompiledPath(root, isRootPath);

36
json-path/src/main/java/com/jayway/jsonpath/internal/Utils.java

@ -75,6 +75,42 @@ public final class Utils {
return join(delimiter, "", objs); return join(delimiter, "", objs);
} }
public static String concat(CharSequence... strings) {
if (strings.length == 0){
return "";
}
if (strings.length == 1){
return strings[0].toString();
}
int length = 0;
// -1 = no result, -2 = multiple results
int indexOfSingleNonEmptyString = -1;
for (int i = 0; i< strings.length; i++) {
CharSequence charSequence = strings[i];
int len = charSequence.length();
length += len;
if (indexOfSingleNonEmptyString != -2 && len > 0){
if (indexOfSingleNonEmptyString == -1){
indexOfSingleNonEmptyString = i;
} else {
indexOfSingleNonEmptyString = -2;
}
}
}
if (length == 0){
return "";
}
if (indexOfSingleNonEmptyString > 0){
return strings[indexOfSingleNonEmptyString].toString();
}
StringBuilder sb = new StringBuilder(length);
for (CharSequence charSequence : strings) {
sb.append(charSequence);
}
return sb.toString();
}
//--------------------------------------------------------- //---------------------------------------------------------
// //
// IO // IO

4
json-path/src/main/java/com/jayway/jsonpath/internal/token/PathToken.java

@ -40,7 +40,7 @@ public abstract class PathToken {
if(properties.size() == 1) { if(properties.size() == 1) {
String property = properties.get(0); String property = properties.get(0);
String evalPath = currentPath + "['" + property + "']"; String evalPath = Utils.concat(currentPath, "['", property, "']");
Object propertyVal = readObjectProperty(property, model, ctx); Object propertyVal = readObjectProperty(property, model, ctx);
if(propertyVal == JsonProvider.UNDEFINED){ if(propertyVal == JsonProvider.UNDEFINED){
if(isLeaf()) { if(isLeaf()) {
@ -115,7 +115,7 @@ public abstract class PathToken {
void handleArrayIndex(int index, String currentPath, Object model, EvaluationContextImpl ctx) { void handleArrayIndex(int index, String currentPath, Object model, EvaluationContextImpl ctx) {
String evalPath = currentPath + "[" + index + "]"; String evalPath = Utils.concat(currentPath, "[", String.valueOf(index), "]");
PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, index) : PathRef.NO_OP; PathRef pathRef = ctx.forUpdate() ? PathRef.create(model, index) : PathRef.NO_OP;
try { try {
Object evalHit = ctx.jsonProvider().getArrayIndex(model, index); Object evalHit = ctx.jsonProvider().getArrayIndex(model, index);

Loading…
Cancel
Save