Browse Source

Bracket properties can contain path chars #154

pull/158/head
Kalle Stenflo 9 years ago
parent
commit
ea206498cc
  1. 18
      json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java
  2. 3
      json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java
  3. 4
      json-path/src/main/java/com/jayway/jsonpath/internal/path/PathCompiler.java
  4. 8
      json-path/src/main/java/com/jayway/jsonpath/internal/path/PathTokenFactory.java
  5. 6
      json-path/src/main/java/com/jayway/jsonpath/internal/path/PropertyPathToken.java
  6. 14
      json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java
  7. 2
      json-path/src/test/java/com/jayway/jsonpath/PathCompilerTest.java
  8. 2
      json-path/src/test/java/com/jayway/jsonpath/internal/path/PathTokenTest.java

18
json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java

@ -10,6 +10,7 @@ public class CharacterIndex {
private static final char SPACE = ' ';
private static final char ESCAPE = '\\';
private static final char SINGLE_QUOTE = '\'';
private static final char DOUBLE_QUOTE = '"';
private static final char MINUS = '-';
private static final char PERIOD = '.';
private static final char REGEX = '/';
@ -92,6 +93,23 @@ public class CharacterIndex {
break;
}
}
} else if (charAt(readPosition) == DOUBLE_QUOTE) {
boolean escaped = false;
while (inBounds(readPosition)) {
readPosition++;
if (escaped) {
escaped = false;
continue;
}
if (charAt(readPosition) == ESCAPE) {
escaped = true;
continue;
}
if (charAt(readPosition) == DOUBLE_QUOTE) {
readPosition++;
break;
}
}
}
}
if (skipRegex) {

3
json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java

@ -16,6 +16,7 @@ public class FilterCompiler {
private static final char EVAL_CONTEXT = '@';
private static final char OPEN_SQUARE_BRACKET = '[';
private static final char CLOSE_SQUARE_BRACKET = ']';
private static final char OPEN_PARENTHESIS = '(';
private static final char CLOSE_PARENTHESIS = ')';
private static final char OPEN_OBJECT = '{';
@ -301,7 +302,7 @@ public class FilterCompiler {
filter.incrementPosition(1); //skip $ and @
while (filter.inBounds()) {
if (filter.currentChar() == OPEN_SQUARE_BRACKET) {
int closingSquareBracketIndex = filter.indexOfClosingSquareBracket(filter.position());
int closingSquareBracketIndex = filter.indexOfMatchingCloseChar(filter.position(), OPEN_SQUARE_BRACKET, CLOSE_SQUARE_BRACKET, true, false);
if (closingSquareBracketIndex == -1) {
throw new InvalidPathException("Square brackets does not match in filter " + filter);
} else {

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

@ -172,7 +172,7 @@ public class PathCompiler {
if(property.endsWith("()")){
appender.appendPathToken(PathTokenFactory.createFunctionPathToken(property));
} else {
appender.appendPathToken(PathTokenFactory.createSinglePropertyPathToken(property));
appender.appendPathToken(PathTokenFactory.createSinglePropertyPathToken(property, SINGLE_QUOTE));
}
return path.currentIsTail() || readNextToken(appender);
@ -385,7 +385,7 @@ public class PathCompiler {
path.setPosition(endBracketIndex);
appender.appendPathToken(PathTokenFactory.createPropertyPathToken(properties));
appender.appendPathToken(PathTokenFactory.createPropertyPathToken(properties, potentialStringDelimiter));
return path.currentIsTail() || readNextToken(appender);
}

8
json-path/src/main/java/com/jayway/jsonpath/internal/path/PathTokenFactory.java

@ -13,12 +13,12 @@ public class PathTokenFactory {
return new RootPathToken(token);
}
public static PathToken createSinglePropertyPathToken(String property) {
return new PropertyPathToken(singletonList(property));
public static PathToken createSinglePropertyPathToken(String property, char stringDelimiter) {
return new PropertyPathToken(singletonList(property), stringDelimiter);
}
public static PathToken createPropertyPathToken(List<String> properties) {
return new PropertyPathToken(properties);
public static PathToken createPropertyPathToken(List<String> properties, char stringDelimiter) {
return new PropertyPathToken(properties, stringDelimiter);
}
public static PathToken createSliceArrayPathToken(final ArraySliceOperation arraySliceOperation) {

6
json-path/src/main/java/com/jayway/jsonpath/internal/path/PropertyPathToken.java

@ -30,12 +30,14 @@ import static com.jayway.jsonpath.internal.Utils.onlyOneIsTrueNonThrow;
class PropertyPathToken extends PathToken {
private final List<String> properties;
private final String stringDelimiter;
public PropertyPathToken(List<String> properties) {
public PropertyPathToken(List<String> properties, char stringDelimiter) {
if (properties.isEmpty()) {
throw new InvalidPathException("Empty properties");
}
this.properties = properties;
this.stringDelimiter = Character.toString(stringDelimiter);
}
public List<String> getProperties() {
@ -97,7 +99,7 @@ class PropertyPathToken extends PathToken {
public String getPathFragment() {
return new StringBuilder()
.append("[")
.append(Utils.join(",", "'", properties))
.append(Utils.join(",", stringDelimiter, properties))
.append("]").toString();
}
}

14
json-path/src/test/java/com/jayway/jsonpath/FilterCompilerTest.java

@ -42,18 +42,24 @@ public class FilterCompilerTest {
assertThat(compile("[?(((@)))]").toString()).isEqualTo("[?(@)]");
assertThat(compile("[?(@.name =~ /.*?/i)]").toString()).isEqualTo("[?(@['name'] =~ /.*?/i)]");
assertThat(compile("[?(@.name =~ /.*?/)]").toString()).isEqualTo("[?(@['name'] =~ /.*?/)]");
assertThat(compile("[?($[\"firstname\"][\"lastname\"])]").toString()).isEqualTo("[?($['firstname']['lastname'])]");
assertThat(compile("[?($[\"firstname\"].lastname)]").toString()).isEqualTo("[?($['firstname']['lastname'])]");
assertThat(compile("[?($[\"firstname\", \"lastname\"])]").toString()).isEqualTo("[?($['firstname','lastname'])]");
assertThat(compile("[?($[\"firstname\"][\"lastname\"])]").toString()).isEqualTo("[?($[\"firstname\"][\"lastname\"])]");
assertThat(compile("[?($[\"firstname\"].lastname)]").toString()).isEqualTo("[?($[\"firstname\"]['lastname'])]");
assertThat(compile("[?($[\"firstname\", \"lastname\"])]").toString()).isEqualTo("[?($[\"firstname\",\"lastname\"])]");
}
@Test
public void string_quoute_style_is_serialized() {
public void string_quote_style_is_serialized() {
assertThat(compile("[?('apa' == 'apa')]").toString()).isEqualTo("[?('apa' == 'apa')]");
assertThat(compile("[?('apa' == \"apa\")]").toString()).isEqualTo("[?('apa' == \"apa\")]");
}
@Test
public void string_can_contain_path_chars() {
assertThat(compile("[?(@[')]@$)]'] == ')]@$)]')]").toString()).isEqualTo("[?(@[')]@$)]'] == ')]@$)]')]");
assertThat(compile("[?(@[\")]@$)]\"] == \")]@$)]\")]").toString()).isEqualTo("[?(@[\")]@$)]\"] == \")]@$)]\")]");
}
@Test
public void invalid_filters_does_not_compile() {

2
json-path/src/test/java/com/jayway/jsonpath/PathCompilerTest.java

@ -59,7 +59,7 @@ public class PathCompilerTest {
assertThat(compile("$['1prop']").toString()).isEqualTo("$['1prop']");
assertThat(compile("$['@prop']").toString()).isEqualTo("$['@prop']");
assertThat(compile("$[ '@prop' ]").toString()).isEqualTo("$['@prop']");
assertThat(compile("$[\"prop\"]").toString()).isEqualTo("$['prop']");
assertThat(compile("$[\"prop\"]").toString()).isEqualTo("$[\"prop\"]");
}
@Test

2
json-path/src/test/java/com/jayway/jsonpath/internal/path/PathTokenTest.java

@ -33,7 +33,7 @@ public class PathTokenTest extends BaseTest {
private PathToken makePPT(final String ... properties) {
return new PropertyPathToken(Arrays.asList(properties));
return new PropertyPathToken(Arrays.asList(properties), '\'');
}
private PathToken makePathReturningTail(final PathToken ... tokens) {

Loading…
Cancel
Save