8 changed files with 3975 additions and 1 deletions
@ -0,0 +1,90 @@
|
||||
package com.jayway.jsonpath.internal.path; |
||||
|
||||
import com.jayway.jsonpath.internal.PathRef; |
||||
import com.jayway.jsonpath.internal.Utils; |
||||
import com.jayway.jsonpath.spi.json.JsonProvider; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.StringTokenizer; |
||||
|
||||
public class CaretPathToken extends PathToken { |
||||
|
||||
public final static char SINGLE_QUOTE = '\''; |
||||
public final static char CARET = '^'; |
||||
|
||||
@Override |
||||
public void evaluate(String currentPath, PathRef parent, Object model, EvaluationContextImpl ctx) { |
||||
if ( isRoot() ) return; |
||||
String evalPath = Utils.concat(currentPath, getPathFragment()); |
||||
Object p = getParentModel(currentPath, model, ctx); |
||||
if ( p == null ) return; |
||||
PathRef pathRef = ctx.forUpdate() ? parent : PathRef.NO_OP; |
||||
if ( isLeaf() ) { |
||||
ctx.addResult(evalPath, pathRef, p); |
||||
} else { |
||||
next().evaluate(evalPath, pathRef, p, ctx); |
||||
} |
||||
} |
||||
|
||||
private Object getParentModel(final String path, final Object model, final EvaluationContextImpl ctx) { |
||||
Object root = ctx.rootDocument(); |
||||
List list = tokenizePath(path); |
||||
list = list.subList(0, list.size() - getParentDepth(path)); |
||||
Object p = root; |
||||
Object last = null; |
||||
for ( Object o : list ) { |
||||
last = p; |
||||
p = searchObject(o, p, ctx); |
||||
} |
||||
return p; |
||||
} |
||||
private int getParentDepth(final String path) { |
||||
int i = 0; |
||||
while ( true ) { |
||||
if ( path.charAt(path.length() - 1 - i) == CARET ) { |
||||
i++; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
return i; |
||||
} |
||||
|
||||
private Object searchObject(Object key, Object o, final EvaluationContextImpl ctx) { |
||||
if ( key instanceof String ) { |
||||
return ctx.jsonProvider().getMapValue(o, (String)key); |
||||
} else if ( key instanceof Integer ) { |
||||
return ctx.jsonProvider().getArrayIndex(o, (Integer)key); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
private List<Object> tokenizePath(final String path) { |
||||
StringTokenizer st = new StringTokenizer(path, "$[]^"); |
||||
List obj = new ArrayList(); |
||||
while ( st.hasMoreTokens() ) { |
||||
String token = st.nextToken().trim(); |
||||
if ( token.indexOf(SINGLE_QUOTE) == 0 ) { |
||||
obj.add(token.substring(1, token.length() - 1)); |
||||
} else { |
||||
try { |
||||
obj.add(Integer.parseInt(token)); |
||||
} catch ( NumberFormatException ex) { |
||||
; |
||||
} |
||||
} |
||||
} |
||||
return obj; |
||||
} |
||||
@Override |
||||
public boolean isTokenDefinite() { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
protected String getPathFragment() { |
||||
return "^"; |
||||
} |
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.jayway.jsonpath; |
||||
|
||||
import org.junit.Assert; |
||||
import org.junit.Test; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.HashMap; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import static com.jayway.jsonpath.JsonPath.parse; |
||||
import static com.jayway.jsonpath.JsonPath.read; |
||||
import static java.util.Collections.emptyMap; |
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
public class CaretTest extends BaseTest { |
||||
|
||||
private static final Map<String, Object> EMPTY_MAP = emptyMap(); |
||||
|
||||
|
||||
@Test |
||||
public void get_parent_node() { |
||||
|
||||
try(InputStream is = this.getClass().getResourceAsStream("/issue_caret.json")) { |
||||
Object result = read(is, "$..ExtendedResult[?(@.:Type =='ER' && @.:Code == 'FX')].Extension[?(@.:Code == 'PENALTY' && @.:Value)]^^^^^^[':SortOrder']"); |
||||
System.out.println(result.toString()); |
||||
} catch ( IOException ioex) { |
||||
ioex.printStackTrace(); |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
// Helper converter implementation for test cases.
|
||||
private class ToStringMapFunction implements MapFunction { |
||||
|
||||
@Override |
||||
public Object map(Object currentValue, Configuration configuration) { |
||||
return currentValue.toString()+"converted"; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue