Browse Source

Added convert method for path value in-situ conversion.

pull/81/head
Tamas Adam 10 years ago
parent
commit
b5c175d04d
  1. 18
      json-path/src/main/java/com/jayway/jsonpath/JsonPath.java
  2. 21
      json-path/src/main/java/com/jayway/jsonpath/WriteContext.java
  3. 13
      json-path/src/main/java/com/jayway/jsonpath/internal/JsonReader.java
  4. 28
      json-path/src/main/java/com/jayway/jsonpath/internal/PathRef.java
  5. 10
      json-path/src/main/java/com/jayway/jsonpath/internal/ValueConverter.java
  6. 54
      json-path/src/test/java/com/jayway/jsonpath/WriteTest.java

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

@ -15,12 +15,7 @@
package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.EvaluationContext;
import com.jayway.jsonpath.internal.JsonReader;
import com.jayway.jsonpath.internal.Path;
import com.jayway.jsonpath.internal.PathCompiler;
import com.jayway.jsonpath.internal.PathRef;
import com.jayway.jsonpath.internal.Utils;
import com.jayway.jsonpath.internal.*;
import com.jayway.jsonpath.spi.json.JsonProvider;
import java.io.File;
@ -218,6 +213,17 @@ public class JsonPath {
return resultByConfiguration(jsonObject, configuration, evaluationContext);
}
public <T> T convert(Object jsonObject, ValueConverter valueConverter, Configuration configuration) {
notNull(jsonObject, "json can not be null");
notNull(configuration, "configuration can not be null");
EvaluationContext evaluationContext = path.evaluate(jsonObject, jsonObject, configuration, true);
for (PathRef updateOperation : evaluationContext.updateOperations()) {
updateOperation.convert(valueConverter, configuration);
}
return resultByConfiguration(jsonObject, configuration, evaluationContext);
}
/**
* Deletes the object this path points to in the provided jsonObject
*

21
json-path/src/main/java/com/jayway/jsonpath/WriteContext.java

@ -14,6 +14,8 @@
*/
package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.ValueConverter;
public interface WriteContext {
/**
@ -56,6 +58,25 @@ public interface WriteContext {
*/
DocumentContext set(JsonPath path, Object newValue);
/**
* Converts the value on the given path.
*
* @param path path to be converted set
* @param valueConverter Converter object to be invoked (or lambda:))
* @param filters filters
* @return a document context
*/
DocumentContext convert(String path, ValueConverter valueConverter, Predicate... filters);
/**
* Converts the value on the given path.
*
* @param path path to be converted set
* @param valueConverter Converter object to be invoked (or lambda:))
* @return a document context
*/
DocumentContext convert(JsonPath path, ValueConverter valueConverter);
/**
* Deletes the given path
*

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

@ -33,6 +33,7 @@ import java.io.InputStream;
import java.util.List;
import static com.jayway.jsonpath.JsonPath.compile;
import static com.jayway.jsonpath.JsonPath.parse;
import static com.jayway.jsonpath.internal.Utils.notEmpty;
import static com.jayway.jsonpath.internal.Utils.notNull;
@ -194,6 +195,18 @@ public class JsonReader implements ParseContext, DocumentContext {
return this;
}
@Override
public DocumentContext convert(String path, ValueConverter valueConverter, Predicate... filters) {
convert(compile(path, filters), valueConverter);
return this;
}
@Override
public DocumentContext convert(JsonPath path, ValueConverter valueConverter) {
path.convert(json, valueConverter, configuration);
return this;
}
@Override
public DocumentContext delete(String path, Predicate... filters) {
return delete(compile(path, filters));

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

@ -17,6 +17,9 @@ public abstract class PathRef implements Comparable<PathRef> {
@Override
public void set(Object newVal, Configuration configuration) {}
@Override
public void convert(ValueConverter valueConverter, Configuration configuration) {}
@Override
public void delete(Configuration configuration) {}
@ -42,6 +45,8 @@ public abstract class PathRef implements Comparable<PathRef> {
public abstract void set(Object newVal, Configuration configuration);
public abstract void convert(ValueConverter valueConverter, Configuration configuration);
public abstract void delete(Configuration configuration);
public abstract void add(Object newVal, Configuration configuration);
@ -103,6 +108,10 @@ public abstract class PathRef implements Comparable<PathRef> {
throw new InvalidModificationException("Invalid delete operation");
}
public void convert(ValueConverter valueConverter, Configuration configuration){
throw new InvalidModificationException("Invalid convert operation");
}
@Override
public void delete(Configuration configuration) {
throw new InvalidModificationException("Invalid delete operation");
@ -136,6 +145,7 @@ public abstract class PathRef implements Comparable<PathRef> {
}
}
private static class ArrayIndexPathRef extends PathRef {
private int index;
@ -151,6 +161,11 @@ public abstract class PathRef implements Comparable<PathRef> {
configuration.jsonProvider().setArrayIndex(parent, index, newVal);
}
public void convert(ValueConverter valueConverter, Configuration configuration){
Object currentValue = configuration.jsonProvider().getArrayIndex(parent, index);
configuration.jsonProvider().setArrayIndex(parent, index, valueConverter.convert(currentValue));
}
public void delete(Configuration configuration){
configuration.jsonProvider().removeProperty(parent, value);
}
@ -209,6 +224,13 @@ public abstract class PathRef implements Comparable<PathRef> {
configuration.jsonProvider().setProperty(parent, property, newVal);
}
@Override
public void convert(ValueConverter valueConverter, Configuration configuration) {
Object currentValue = configuration.jsonProvider().getMapValue(parent, property);
configuration.jsonProvider().setProperty(parent, property, valueConverter.convert(currentValue));
}
public void delete(Configuration configuration){
configuration.jsonProvider().removeProperty(parent, property);
}
@ -266,6 +288,12 @@ public abstract class PathRef implements Comparable<PathRef> {
configuration.jsonProvider().setProperty(parent, property, newVal);
}
}
public void convert(ValueConverter valueConverter, Configuration configuration) {
for (String property : properties) {
Object currentValue = configuration.jsonProvider().getMapValue(parent, property);
configuration.jsonProvider().setProperty(parent, property, valueConverter.convert(currentValue));
}
}
public void delete(Configuration configuration){
for (String property : properties) {

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

@ -0,0 +1,10 @@
package com.jayway.jsonpath.internal;
/**
* Created by tom on 29/04/15.
*/
public interface ValueConverter {
public Object convert(Object currentValue);
}

54
json-path/src/test/java/com/jayway/jsonpath/WriteTest.java

@ -1,5 +1,6 @@
package com.jayway.jsonpath;
import com.jayway.jsonpath.internal.ValueConverter;
import org.junit.Test;
import java.util.*;
@ -259,4 +260,57 @@ public class WriteTest extends BaseTest {
public void non_existent_key_rename_not_allowed(){
Object o = parse(JSON_DOCUMENT).renameKey("$", "fake", "new-fake").json();
}
@Test(expected = InvalidModificationException.class)
public void rootCannotBeConverted(){
ValueConverter valueConverter = new ValueConverter() {
@Override
public Object convert(Object currentValue) {
return currentValue.toString()+"converted";
}
};
Object o = parse(JSON_DOCUMENT).convert("$", valueConverter).json();
}
@Test
public void single_match_value_can_be_converted(){
ValueConverter valueConverter = new ToStringValueConverterImpl();
String stringResult = parse(JSON_DOCUMENT).convert("$.string-property", valueConverter).read("$.string-property");
assertThat(stringResult.endsWith("converted")).isTrue();
}
@Test
public void object_can_be_converted(){
ValueConverter valueConverter = new ToStringValueConverterImpl();
DocumentContext documentContext = parse(JSON_DOCUMENT);
Object list = documentContext.read("$..book");
assertThat(list).isInstanceOf(List.class);
String result = ((List<String>)documentContext.convert("$..book", valueConverter).read("$..book")).get(0);
assertThat(result).isInstanceOf(String.class);
assertThat(((String)result).endsWith("converted")).isTrue();
}
@Test
public void multi_match_path_can_be_converted(){
ValueConverter valueConverter = new ToStringValueConverterImpl();
List<Double> doubleResult = parse(JSON_DOCUMENT).read("$..display-price");
for(Double dRes : doubleResult){
assertThat(dRes).isInstanceOf(Double.class);
}
List<String> stringResult = parse(JSON_DOCUMENT).convert("$..display-price", valueConverter).read("$..display-price");
for(String sRes : stringResult){
assertThat(sRes).isInstanceOf(String.class);
assertThat(sRes.endsWith("converted")).isTrue();
}
}
// Helper converter implementation for test cases.
private class ToStringValueConverterImpl implements ValueConverter{
@Override
public Object convert(Object currentValue) {
return currentValue.toString()+"converted";
}
}
}
Loading…
Cancel
Save