Skip to content

Commit 33f365e

Browse files
committed
Removed % prefix from path functions.
1 parent fd2ac6c commit 33f365e

File tree

9 files changed

+42
-78
lines changed

9 files changed

+42
-78
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,19 @@ Operators
6262
| `[?(<expression>)]` | Filter expression. Expression must evaluate to a boolean value. |
6363

6464
<!---
65-
Functions (not released yet)
65+
Functions
6666
---------
6767
6868
Functions can be invoked at the tail end of a path - the input to a function is the output of the path expression.
6969
The function output is dictated by the function itself.
7070
7171
| Function | Description | Output |
7272
| :------------------------ | :----------------------------------------------------------------- |-----------|
73-
| %min() | Provides the min value of an array of numbers | Double |
74-
| %max() | Provides the max value of an array of numbers | Double |
75-
| %avg() | Provides the average value of an array of numbers | Double |
76-
| %stddev() | Provides the standard deviation value of an array of numbers | Double |
77-
| %length() | Provides the length of an array | Integer |
73+
| min() | Provides the min value of an array of numbers | Double |
74+
| max() | Provides the max value of an array of numbers | Double |
75+
| avg() | Provides the average value of an array of numbers | Double |
76+
| stddev() | Provides the standard deviation value of an array of numbers | Double |
77+
| length() | Provides the length of an array | Integer |
7878
-->
7979

8080
Path Examples
@@ -141,7 +141,7 @@ Given the json
141141
| <a href="http://jsonpath.herokuapp.com/?path=$..book[?(@.author =~ /.*REES/i)]" target="_blank">$..book[?(@.author =~ /.*REES/i)]</a> | All books matching regex (ignore case) |
142142
| <a href="http://jsonpath.herokuapp.com/?path=$..*" target="_blank">$..*</a> | Give me every thing
143143
<!---
144-
| <a href="http://jsonpath.herokuapp.com/?path=$..book.%length()" target="_blank">$..book.%length()</a> | The number of books |
144+
| <a href="http://jsonpath.herokuapp.com/?path=$..book.length()" target="_blank">$..book.%length()</a> | The number of books |
145145
-->
146146
Reading a Document
147147
------------------

json-path/src/main/java/com/jayway/jsonpath/JsonPath.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,10 @@ public <T> T read(Object jsonObject, Configuration configuration) {
179179
throw new JsonPathException("Options " + AS_PATH_LIST + " and " + ALWAYS_RETURN_LIST + " are not allowed when using path functions!");
180180
}
181181
return path.evaluate(jsonObject, jsonObject, configuration).getValue(true);
182-
}
183-
if(optAsPathList){
182+
183+
} else if(optAsPathList){
184184
return (T)path.evaluate(jsonObject, jsonObject, configuration).getPath();
185+
185186
} else {
186187
Object res = path.evaluate(jsonObject, jsonObject, configuration).getValue(false);
187188
if(optAlwaysReturnList && path.isDefinite()){

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

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public class PathCompiler {
2424
private static final char OPEN_SQUARE_BRACKET = '[';
2525
private static final char CLOSE_SQUARE_BRACKET = ']';
2626
private static final char OPEN_BRACKET = '(';
27-
private static final char CLOSE_BRACKET = ')';
2827
private static final char WILDCARD = '*';
2928
private static final char PERIOD = '.';
3029
private static final char SPACE = ' ';
@@ -33,7 +32,6 @@ public class PathCompiler {
3332
private static final char SPLIT = ':';
3433
private static final char MINUS = '-';
3534
private static final char TICK = '\'';
36-
private static final char FUNCTION = '%';
3735

3836
private final LinkedList<Predicate> filterStack;
3937
private final CharacterIndex path;
@@ -118,42 +116,12 @@ private boolean readNextToken(PathTokenAppender appender) {
118116
case WILDCARD:
119117
return readWildCardToken(appender) ||
120118
fail("Could not parse token starting at position " + path.position());
121-
case FUNCTION:
122-
return readFunctionToken(appender) ||
123-
fail("Could not parse token starting at position " + path.position());
124119
default:
125-
return readPropertyToken(appender) ||
120+
return readPropertyOrFunctionToken(appender) ||
126121
fail("Could not parse token starting at position " + path.position());
127122
}
128123
}
129124

130-
//
131-
// $function()
132-
//
133-
private boolean readFunctionToken(PathTokenAppender appender) {
134-
if (path.currentCharIs(OPEN_SQUARE_BRACKET) || path.currentCharIs(WILDCARD) || path.currentCharIs(PERIOD) || path.currentCharIs(SPACE)) {
135-
return false;
136-
}
137-
int startPosition = path.position();
138-
int readPosition = startPosition;
139-
int endPosition = 0;
140-
while (path.inBounds(readPosition)) {
141-
char c = path.charAt(readPosition);
142-
if (c == OPEN_BRACKET && path.nextSignificantCharIs(readPosition, CLOSE_BRACKET)) {
143-
endPosition = path.indexOfNextSignificantChar(readPosition, CLOSE_BRACKET);
144-
break;
145-
}
146-
readPosition++;
147-
}
148-
path.setPosition(endPosition);
149-
150-
String function = path.subSequence(startPosition, endPosition + 1).toString();
151-
152-
appender.appendPathToken(PathTokenFactory.createFunctionPathToken(function));
153-
154-
return path.currentIsTail();
155-
}
156-
157125
//
158126
// . and ..
159127
//
@@ -173,9 +141,9 @@ private boolean readDotToken(PathTokenAppender appender) {
173141
}
174142

175143
//
176-
// fooBar
144+
// fooBar or fooBar()
177145
//
178-
private boolean readPropertyToken(PathTokenAppender appender) {
146+
private boolean readPropertyOrFunctionToken(PathTokenAppender appender) {
179147
if (path.currentCharIs(OPEN_SQUARE_BRACKET) || path.currentCharIs(WILDCARD) || path.currentCharIs(PERIOD) || path.currentCharIs(SPACE)) {
180148
return false;
181149
}
@@ -201,8 +169,11 @@ private boolean readPropertyToken(PathTokenAppender appender) {
201169
path.setPosition(endPosition);
202170

203171
String property = path.subSequence(startPosition, endPosition).toString();
204-
205-
appender.appendPathToken(PathTokenFactory.createSinglePropertyPathToken(property));
172+
if(property.endsWith("()")){
173+
appender.appendPathToken(PathTokenFactory.createFunctionPathToken(property));
174+
} else {
175+
appender.appendPathToken(PathTokenFactory.createSinglePropertyPathToken(property));
176+
}
206177

207178
return path.currentIsTail() || readNextToken(appender);
208179
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ public class FilterCompiler {
1313
private static final Logger logger = LoggerFactory.getLogger(FilterCompiler.class);
1414

1515
private static final char DOC_CONTEXT = '$';
16-
private static final char EVAL_CONTEXT = '@';
16+
private static final char EVAL_CONTEXT = '@'; /**/
1717
private static final char OPEN_SQUARE_BRACKET = '[';
1818
private static final char OPEN_BRACKET = '(';
1919
private static final char CLOSE_BRACKET = ')';
2020
private static final char SPACE = ' ';
2121
private static final char MINUS = '-';
2222
private static final char TICK = '\'';
23-
private static final char FUNCTION = '%';
23+
private static final char PERIOD = '.';
2424
private static final char LT = '<';
2525
private static final char GT = '>';
2626
private static final char EQ = '=';
@@ -338,7 +338,7 @@ private boolean currentCharIsClosingFunctionBracket(int lowerBound){
338338
}
339339
idx--;
340340
while(filter.inBounds(idx) && idx > lowerBound){
341-
if(filter.charAt(idx) == FUNCTION){
341+
if(filter.charAt(idx) == PERIOD){
342342
return true;
343343
}
344344
idx--;
@@ -349,6 +349,7 @@ private boolean currentCharIsClosingFunctionBracket(int lowerBound){
349349
private boolean isLogicalOperatorChar(char c) {
350350
return c == AND || c == OR;
351351
}
352+
352353
private boolean isRelationalOperatorChar(char c) {
353354
return c == LT || c == GT || c == EQ || c == TILDE || c == BANG;
354355
}

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
import com.jayway.jsonpath.internal.function.Function;
55
import com.jayway.jsonpath.internal.function.FunctionFactory;
66

7-
import java.util.regex.Matcher;
8-
import java.util.regex.Pattern;
9-
107
/**
118
* Token representing a Function call to one of the functions produced via the FunctionFactory
129
*
@@ -21,12 +18,9 @@ public class FunctionPathToken extends PathToken {
2118

2219
public FunctionPathToken(String pathFragment) {
2320
this.pathFragment = pathFragment;
24-
Matcher matcher = Pattern.compile(".*?\\%(\\w+)\\(.*?").matcher(pathFragment);
25-
if (matcher.matches()) {
26-
functionName = matcher.group(1);
27-
}
28-
else {
29-
// We'll end up throwing an error from the factory when we get that far
21+
if(pathFragment.endsWith("()")){
22+
functionName = pathFragment.substring(0, pathFragment.length()-2);
23+
} else {
3024
functionName = null;
3125
}
3226
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ public void valid_filters_compile() {
3636
assertThat(compile("[?(@.a IN {'foo':'bar'})]").toString()).isEqualTo("[?(@['a'] IN {'foo':'bar'})]");
3737
assertThat(compile("[?(@.value<'7')]").toString()).isEqualTo("[?(@['value'] < '7')]");
3838
assertThat(compile("[?(@.message == 'it\\\\')]").toString()).isEqualTo("[?(@['message'] == 'it\\\\')]");
39-
assertThat(compile("[?(@.message.%min() > 10)]").toString()).isEqualTo("[?(@['message'].%min() > 10)]");
40-
assertThat(compile("[?(@.message.%min()==10)]").toString()).isEqualTo("[?(@['message'].%min() == 10)]");
41-
assertThat(compile("[?(10 == @.message.%min())]").toString()).isEqualTo("[?(10 == @['message'].%min())]");
39+
assertThat(compile("[?(@.message.min() > 10)]").toString()).isEqualTo("[?(@['message'].min() > 10)]");
40+
assertThat(compile("[?(@.message.min()==10)]").toString()).isEqualTo("[?(@['message'].min() == 10)]");
41+
assertThat(compile("[?(10 == @.message.min())]").toString()).isEqualTo("[?(10 == @['message'].min())]");
4242
assertThat(compile("[?(((@)))]").toString()).isEqualTo("[?(@)]");
4343
assertThat(compile("[?(@.name =~ /.*?/i)]").toString()).isEqualTo("[?(@['name'] =~ /.*?/i)]");
4444
assertThat(compile("[?(@.name =~ /.*?/)]").toString()).isEqualTo("[?(@['name'] =~ /.*?/)]");

json-path/src/test/java/com/jayway/jsonpath/FilterTest.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,11 +482,8 @@ public void criteria_can_be_parsed() {
482482

483483

484484
@Test
485-
public void inline_in_criteria_evalueates() {
486-
487-
Object read = JsonPath.read(JSON_DOCUMENT, "$.store.book[?(@.category in ['reference', 'fiction'])]");
488-
489-
System.out.println(read);
490-
485+
public void inline_in_criteria_evaluates() {
486+
List list = JsonPath.read(JSON_DOCUMENT, "$.store.book[?(@.category in ['reference', 'fiction'])]");
487+
assertThat(list).hasSize(4);
491488
}
492489
}

json-path/src/test/java/com/jayway/jsonpath/functions/JSONEntityFunctionTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,18 @@ public class JSONEntityFunctionTest extends BaseFunctionTest {
5454
@Test
5555
public void testLengthOfTextArray() {
5656
// The length of JSONArray is an integer
57-
verifyFunction(conf, "$['text'].%length()", TEXT_SERIES, 6);
57+
verifyFunction(conf, "$['text'].length()", TEXT_SERIES, 6);
5858
}
5959
@Test
6060
public void testLengthOfNumberArray() {
6161
// The length of JSONArray is an integer
62-
verifyFunction(conf, "$.numbers.%length()", NUMBER_SERIES, 10);
62+
verifyFunction(conf, "$.numbers.length()", NUMBER_SERIES, 10);
6363
}
6464

6565

6666
@Test
6767
public void testLengthOfStructure() {
68-
verifyFunction(conf, "$.batches.%length()", BATCH_JSON, 2);
68+
verifyFunction(conf, "$.batches.length()", BATCH_JSON, 2);
6969
}
7070

7171
/**
@@ -80,7 +80,7 @@ public void testLengthOfStructure() {
8080
*/
8181
@Test
8282
public void testPredicateWithFunctionCallSingleMatch() {
83-
String path = "$.batches.results[?(@.values.%length() >= $.batches.minBatchSize)].values.%avg()";
83+
String path = "$.batches.results[?(@.values.length() >= $.batches.minBatchSize)].values.avg()";
8484

8585
// Its an array because in some use-cases the min size might match more than one batch and thus we'll get
8686
// the average out for each collection
@@ -91,7 +91,7 @@ public void testPredicateWithFunctionCallSingleMatch() {
9191

9292
@Test
9393
public void testPredicateWithFunctionCallTwoMatches() {
94-
String path = "$.batches.results[?(@.values.%length() >= 3)].values.%avg()";
94+
String path = "$.batches.results[?(@.values.length() >= 3)].values.avg()";
9595

9696
// Its an array because in some use-cases the min size might match more than one batch and thus we'll get
9797
// the average out for each collection

json-path/src/test/java/com/jayway/jsonpath/functions/NumericFunctionTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,27 @@ public static Iterable<Configuration> configurations() {
4242

4343
@Test
4444
public void testAverageOfDoubles() {
45-
verifyMathFunction(conf, "$.numbers.%avg()", 5.5);
45+
verifyMathFunction(conf, "$.numbers.avg()", 5.5);
4646
}
4747

4848
@Test
4949
public void testSumOfDouble() {
50-
verifyMathFunction(conf, "$.numbers.%sum()", (10d * (10d + 1d)) / 2d);
50+
verifyMathFunction(conf, "$.numbers.sum()", (10d * (10d + 1d)) / 2d);
5151
}
5252

5353
@Test
5454
public void testMaxOfDouble() {
55-
verifyMathFunction(conf, "$.numbers.%max()", 10d);
55+
verifyMathFunction(conf, "$.numbers.max()", 10d);
5656
}
5757

5858
@Test
5959
public void testMinOfDouble() {
60-
verifyMathFunction(conf, "$.numbers.%min()", 1d);
60+
verifyMathFunction(conf, "$.numbers.min()", 1d);
6161
}
6262

6363
@Test
6464
public void testStdDevOfDouble() {
65-
verifyMathFunction(conf, "$.numbers.%stddev()", 2.8722813232690143d);
65+
verifyMathFunction(conf, "$.numbers.stddev()", 2.8722813232690143d);
6666
}
6767

6868
/**
@@ -73,7 +73,7 @@ public void testStdDevOfDouble() {
7373
// public void testInvalidFunctionNameNegative() {
7474
// JSONArray numberSeries = new JSONArray();
7575
// numberSeries.addAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
76-
// assertThat(using(conf).parse(NUMBER_SERIES).read("$.numbers.%foo()")).isEqualTo(numberSeries);
76+
// assertThat(using(conf).parse(NUMBER_SERIES).read("$.numbers.foo()")).isEqualTo(numberSeries);
7777
// }
7878

7979
}

0 commit comments

Comments
 (0)