mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 23:56:36 +00:00
#377 - Add back support for JsonWriteBeanVisitor
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
/**
|
||||
* Allows for customising the JSON write processing.
|
||||
* <p>
|
||||
* You can use this to add raw JSON content via {@link JsonWriter}.
|
||||
* <p>
|
||||
* You register a JsonWriteBeanVisitor with {@link JsonWriteOptions}.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* the type of entity bean
|
||||
*
|
||||
* @see JsonWriteOptions
|
||||
*/
|
||||
public interface JsonWriteBeanVisitor<T> {
|
||||
|
||||
/**
|
||||
* Visit the bean that has just been writing it's content to JSON. You can
|
||||
* write your own additional JSON content to the JsonWriter if you wish.
|
||||
*
|
||||
* @param bean
|
||||
* the bean that has been writing it's content
|
||||
* @param jsonWriter
|
||||
* the JsonWriter which you can append custom json content to if you
|
||||
* wish.
|
||||
*/
|
||||
void visit(T bean, JsonWriter jsonWriter);
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package com.avaje.ebean.text.json;
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides options for customising the JSON write process.
|
||||
* <p>
|
||||
@@ -18,6 +21,8 @@ public class JsonWriteOptions {
|
||||
|
||||
protected JsonConfig.Include include;
|
||||
|
||||
protected Map<String, JsonWriteBeanVisitor<?>> visitorMap;
|
||||
|
||||
/**
|
||||
* Parse and return a PathProperties from nested string format like
|
||||
* (a,b,c(d,e),f(g)) where "c" is a path containing "d" and "e" and "f" is a
|
||||
@@ -67,6 +72,31 @@ public class JsonWriteOptions {
|
||||
this.include = include;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JsonWriteBeanVisitor for the root level.
|
||||
*/
|
||||
public JsonWriteOptions setRootPathVisitor(JsonWriteBeanVisitor<?> visitor) {
|
||||
return setPathVisitor(null, visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JsonWriteBeanVisitor for the given path.
|
||||
*/
|
||||
public JsonWriteOptions setPathVisitor(String path, JsonWriteBeanVisitor<?> visitor) {
|
||||
if (visitorMap == null) {
|
||||
visitorMap = new HashMap<String, JsonWriteBeanVisitor<?>>();
|
||||
}
|
||||
visitorMap.put(path, visitor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Map of registered JsonWriteBeanVisitor's by path.
|
||||
*/
|
||||
public Map<String, JsonWriteBeanVisitor<?>> getVisitorMap() {
|
||||
return visitorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the jackson object mapper to use.
|
||||
* <p/>
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Wraps an underlying JsonGenerator taking into account null suppression and exposing isIncludeEmpty() etc.
|
||||
*/
|
||||
public interface JsonWriter {
|
||||
|
||||
/**
|
||||
* Return the Jackson core JsonGenerator.
|
||||
*/
|
||||
JsonGenerator gen();
|
||||
|
||||
/**
|
||||
* Return true if null values should be included in JSON output.
|
||||
*/
|
||||
boolean isIncludeNull();
|
||||
|
||||
/**
|
||||
* Return true if empty collections should be included in the JSON output.
|
||||
*/
|
||||
boolean isIncludeEmpty();
|
||||
|
||||
/**
|
||||
* Write a field name followed by object start.
|
||||
*/
|
||||
void writeStartObject(String key);
|
||||
|
||||
/**
|
||||
* Write a object start.
|
||||
*/
|
||||
void writeStartObject();
|
||||
|
||||
/**
|
||||
* Write a object end.
|
||||
*/
|
||||
void writeEndObject();
|
||||
|
||||
/**
|
||||
* Write a field name followed by array start.
|
||||
*/
|
||||
void writeStartArray(String key);
|
||||
|
||||
/**
|
||||
* Write a array start.
|
||||
*/
|
||||
void writeStartArray();
|
||||
|
||||
/**
|
||||
* Write a array end.
|
||||
*/
|
||||
void writeEndArray();
|
||||
|
||||
/**
|
||||
* Write the field name.
|
||||
*/
|
||||
void writeFieldName(String name);
|
||||
|
||||
/**
|
||||
* Write a null value taking into account null value suppression.
|
||||
*/
|
||||
void writeNullField(String name);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, int value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, short value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, long value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, double value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, float value);
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, BigDecimal value);
|
||||
|
||||
/**
|
||||
* Write a sting field.
|
||||
*/
|
||||
void writeStringField(String name, String value);
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinary(InputStream is, int length);
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinaryField(String name, byte[] value);
|
||||
|
||||
/**
|
||||
* Write a boolean field.
|
||||
*/
|
||||
void writeBooleanField(String name, boolean value);
|
||||
|
||||
/**
|
||||
* Write a boolean value (typically inside a list).
|
||||
*/
|
||||
void writeBoolean(boolean value);
|
||||
|
||||
/**
|
||||
* Write a string value (typically inside a list).
|
||||
*/
|
||||
void writeString(String value);
|
||||
|
||||
/**
|
||||
* Write a int value (typically inside a list).
|
||||
*/
|
||||
void writeNumber(int value);
|
||||
|
||||
/**
|
||||
* Write a long value (typically inside a list).
|
||||
*/
|
||||
void writeNumber(long value);
|
||||
|
||||
/**
|
||||
* Write a BigDecimal value (typically inside a list).
|
||||
*/
|
||||
void writeNumber(BigDecimal value);
|
||||
|
||||
/**
|
||||
* Write a null value.
|
||||
*/
|
||||
void writeNull();
|
||||
|
||||
/**
|
||||
* Method that will force generator to copy
|
||||
* input text verbatim with <b>no</b> modifications (including
|
||||
* that no escaping is done and no separators are added even
|
||||
* if context [array, object] would otherwise require such).
|
||||
* If such separators are desired, use
|
||||
* {@link #writeRawValue(String)} instead.
|
||||
*/
|
||||
void writeRaw(String text);
|
||||
|
||||
/**
|
||||
* Method that will force generator to copy
|
||||
* input text verbatim without any modifications, but assuming
|
||||
* it must constitute a single legal JSON value (number, string,
|
||||
* boolean, null, Array or List). Assuming this, proper separators
|
||||
* are added if and as needed (comma or colon), and generator
|
||||
* state updated to reflect this.
|
||||
*/
|
||||
void writeRawValue(String text);
|
||||
}
|
||||
@@ -141,11 +141,11 @@ public final class BeanListHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
if (!list.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.writeStartArray(name);
|
||||
ctx.beginAssocMany(name);
|
||||
for (int j = 0; j < list.size(); j++) {
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean) list.get(j));
|
||||
}
|
||||
ctx.writeEndArray();
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,12 +179,12 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
if (!map.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.writeStartArray(name);
|
||||
ctx.beginAssocMany(name);
|
||||
for (Entry<?, ?> entry : map.entrySet()) {
|
||||
//FIXME: json write map key ...
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean) entry.getValue());
|
||||
}
|
||||
ctx.writeEndArray();
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -140,11 +140,11 @@ public final class BeanSetHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
if (!set.isEmpty() || ctx.isIncludeEmpty()) {
|
||||
ctx.writeStartArray(name);
|
||||
ctx.beginAssocMany(name);
|
||||
for (Object bean : set) {
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean) bean);
|
||||
}
|
||||
ctx.writeEndArray();
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,7 +286,8 @@ public class DJsonContext implements JsonContext {
|
||||
|
||||
private WriteJson createWriteJson(JsonGenerator gen, JsonWriteOptions options) {
|
||||
PathProperties pathProps = (options == null) ? null : options.getPathProperties();
|
||||
return new WriteJson(server, gen, pathProps, determineObjectMapper(options), determineInclude(options));
|
||||
Map<String, JsonWriteBeanVisitor<?>> visitors = (options == null) ? null : options.getVisitorMap();
|
||||
return new WriteJson(server, gen, pathProps, visitors, determineObjectMapper(options), determineInclude(options));
|
||||
}
|
||||
|
||||
private <T> void toJsonFromCollection(Collection<T> collection, String key, JsonGenerator gen, JsonWriteOptions options) throws IOException {
|
||||
|
||||
@@ -3,10 +3,12 @@ package com.avaje.ebeaninternal.server.text.json;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebean.text.json.JsonIOException;
|
||||
import com.avaje.ebean.text.json.JsonWriteBeanVisitor;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.type.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.util.ArrayStack;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -21,11 +23,13 @@ import java.util.Set;
|
||||
public class WriteJson implements JsonWriter {
|
||||
|
||||
private final SpiEbeanServer server;
|
||||
|
||||
|
||||
private final JsonGenerator generator;
|
||||
|
||||
|
||||
private final PathProperties pathProperties;
|
||||
|
||||
private final Map<String, JsonWriteBeanVisitor<?>> visitors;
|
||||
|
||||
private final PathStack pathStack;
|
||||
|
||||
private final ArrayStack<Object> parentBeans;
|
||||
@@ -37,10 +41,13 @@ public class WriteJson implements JsonWriter {
|
||||
/**
|
||||
* Construct for full bean use (normal).
|
||||
*/
|
||||
public WriteJson(SpiEbeanServer server, JsonGenerator generator, PathProperties pathProperties, Object objectMapper, JsonConfig.Include include){
|
||||
public WriteJson(SpiEbeanServer server, JsonGenerator generator, PathProperties pathProperties,
|
||||
Map<String, JsonWriteBeanVisitor<?>> visitors, Object objectMapper, JsonConfig.Include include) {
|
||||
|
||||
this.server = server;
|
||||
this.generator = generator;
|
||||
this.pathProperties = pathProperties;
|
||||
this.visitors = visitors;
|
||||
this.objectMapper = objectMapper;
|
||||
this.include = include;
|
||||
this.parentBeans = new ArrayStack<Object>();
|
||||
@@ -50,9 +57,10 @@ public class WriteJson implements JsonWriter {
|
||||
/**
|
||||
* Construct for Json scalar use.
|
||||
*/
|
||||
public WriteJson(JsonGenerator generator, JsonConfig.Include include){
|
||||
public WriteJson(JsonGenerator generator, JsonConfig.Include include) {
|
||||
this.generator = generator;
|
||||
this.include = include;
|
||||
this.visitors = null;
|
||||
this.server = null;
|
||||
this.pathProperties = null;
|
||||
this.objectMapper = null;
|
||||
@@ -74,72 +82,253 @@ public class WriteJson implements JsonWriter {
|
||||
return include != JsonConfig.Include.NON_EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonGenerator gen() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFieldName(String name) throws IOException {
|
||||
generator.writeFieldName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNullField(String name) throws IOException {
|
||||
if (isIncludeNull()) {
|
||||
generator.writeNullField(name);
|
||||
public void writeStartObject(String key) {
|
||||
try {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartObject();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Long value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeStartObject() {
|
||||
try {
|
||||
generator.writeStartObject();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Double value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeEndObject() {
|
||||
try {
|
||||
generator.writeEndObject();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, int value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeStartArray(String key) {
|
||||
try {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Short value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeStartArray() {
|
||||
try {
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEndArray() {
|
||||
try {
|
||||
generator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRaw(String text) {
|
||||
try {
|
||||
generator.writeRaw(text);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeRawValue(String text) {
|
||||
try {
|
||||
generator.writeRawValue(text);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFieldName(String name) {
|
||||
try {
|
||||
generator.writeFieldName(name);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNullField(String name) {
|
||||
if (isIncludeNull()) {
|
||||
try {
|
||||
generator.writeNullField(name);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, long value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, double value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, int value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, short value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, Float value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeNumberField(String name, float value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeNumberField(String name, BigDecimal value) throws IOException {
|
||||
generator.writeNumberField(name, value);
|
||||
public void writeNumberField(String name, BigDecimal value) {
|
||||
try {
|
||||
generator.writeNumberField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeStringField(String name, String value) throws IOException {
|
||||
generator.writeStringField(name, value);
|
||||
public void writeStringField(String name, String value) {
|
||||
try {
|
||||
generator.writeStringField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinary(InputStream is, int length) throws IOException {
|
||||
generator.writeBinary(is, length);
|
||||
public void writeBinary(InputStream is, int length) {
|
||||
try {
|
||||
generator.writeBinary(is, length);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinaryField(String name, byte[] value) throws IOException {
|
||||
generator.writeBinaryField(name, value);
|
||||
public void writeBinaryField(String name, byte[] value) {
|
||||
try {
|
||||
generator.writeBinaryField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBooleanField(String name, Boolean value) throws IOException {
|
||||
generator.writeBooleanField(name, value);
|
||||
public void writeBooleanField(String name, boolean value) {
|
||||
try {
|
||||
generator.writeBooleanField(name, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(boolean value) {
|
||||
try {
|
||||
generator.writeBoolean(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(String value) {
|
||||
try {
|
||||
generator.writeString(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumber(int value) {
|
||||
try {
|
||||
generator.writeNumber(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumber(long value) {
|
||||
try {
|
||||
generator.writeNumber(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNumber(BigDecimal value) {
|
||||
try {
|
||||
generator.writeNumber(value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeNull() {
|
||||
try {
|
||||
generator.writeNull();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isParentBean(Object bean) {
|
||||
@@ -164,65 +353,90 @@ public class WriteJson implements JsonWriter {
|
||||
pathStack.pop();
|
||||
}
|
||||
|
||||
public void beginAssocMany(String key) {
|
||||
try {
|
||||
pathStack.pushPathKey(key);
|
||||
generator.writeFieldName(key);
|
||||
generator.writeStartArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void endAssocMany() {
|
||||
try {
|
||||
pathStack.pop();
|
||||
generator.writeEndArray();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public WriteBean createWriteBean(BeanDescriptor<?> desc, EntityBean bean) {
|
||||
|
||||
String path = pathStack.peekWithNull();
|
||||
JsonWriteBeanVisitor visitor = (visitors == null) ? null : visitors.get(path);
|
||||
if (pathProperties == null) {
|
||||
return new WriteBean(desc, bean);
|
||||
return new WriteBean(desc, bean, visitor);
|
||||
}
|
||||
|
||||
|
||||
boolean explicitAllProps = false;
|
||||
Set<String> currentIncludeProps = pathProperties.get(pathStack.peekWithNull());
|
||||
Set<String> currentIncludeProps = pathProperties.get(path);
|
||||
if (currentIncludeProps != null) {
|
||||
explicitAllProps = currentIncludeProps.contains("*");
|
||||
if (explicitAllProps || currentIncludeProps.isEmpty()) {
|
||||
currentIncludeProps = null;
|
||||
}
|
||||
}
|
||||
return new WriteBean(desc, explicitAllProps, currentIncludeProps, bean);
|
||||
return new WriteBean(desc, explicitAllProps, currentIncludeProps, bean, visitor);
|
||||
}
|
||||
|
||||
public void writeValueUsingObjectMapper(String name, Object value) throws IOException {
|
||||
public void writeValueUsingObjectMapper(String name, Object value) {
|
||||
|
||||
if (!isIncludeEmpty()) {
|
||||
// check for suppression of empty collection or map
|
||||
if (value instanceof Collection && ((Collection)value).isEmpty()) {
|
||||
if (value instanceof Collection && ((Collection) value).isEmpty()) {
|
||||
// suppress empty collection
|
||||
return;
|
||||
} else if (value instanceof Map && ((Map)value).isEmpty()) {
|
||||
} else if (value instanceof Map && ((Map) value).isEmpty()) {
|
||||
// suppress empty map
|
||||
return;
|
||||
}
|
||||
}
|
||||
generator.writeFieldName(name);
|
||||
objectMapper().writeValue(generator, value);
|
||||
try {
|
||||
generator.writeFieldName(name);
|
||||
objectMapper().writeValue(generator, value);
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectMapper objectMapper() {
|
||||
if (objectMapper == null) {
|
||||
throw new IllegalStateException(
|
||||
"Jackson ObjectMapper required but not set. Expected to be set on either"
|
||||
+" serverConfig");
|
||||
throw new IllegalStateException("Jackson ObjectMapper required but not set. Expected to be set on either serverConfig");
|
||||
}
|
||||
return (ObjectMapper)objectMapper;
|
||||
return (ObjectMapper) objectMapper;
|
||||
}
|
||||
|
||||
public static class WriteBean {
|
||||
|
||||
|
||||
final boolean explicitAllProps;
|
||||
final Set<String> currentIncludeProps;
|
||||
final BeanDescriptor<?> desc;
|
||||
final EntityBean currentBean;
|
||||
|
||||
WriteBean(BeanDescriptor<?> desc, EntityBean currentBean){
|
||||
this(desc, false, null, currentBean);
|
||||
final JsonWriteBeanVisitor visitor;
|
||||
|
||||
WriteBean(BeanDescriptor<?> desc, EntityBean currentBean, JsonWriteBeanVisitor visitor) {
|
||||
this(desc, false, null, currentBean, visitor);
|
||||
}
|
||||
|
||||
WriteBean(BeanDescriptor<?> desc, boolean explicitAllProps, Set<String> currentIncludeProps, EntityBean currentBean) {
|
||||
WriteBean(BeanDescriptor<?> desc, boolean explicitAllProps, Set<String> currentIncludeProps, EntityBean currentBean, JsonWriteBeanVisitor visitor) {
|
||||
super();
|
||||
this.desc = desc;
|
||||
this.currentBean = currentBean;
|
||||
this.explicitAllProps = explicitAllProps;
|
||||
this.currentIncludeProps = currentIncludeProps;
|
||||
this.visitor = visitor;
|
||||
}
|
||||
|
||||
private boolean isReferenceOnly() {
|
||||
@@ -251,34 +465,43 @@ public class WriteJson implements JsonWriter {
|
||||
}
|
||||
}
|
||||
|
||||
public void write(WriteJson writeJson) throws IOException {
|
||||
|
||||
BeanProperty beanProp = desc.getIdProperty();
|
||||
if (beanProp != null) {
|
||||
if (isIncludeProperty(beanProp)) {
|
||||
beanProp.jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isReferenceOnly()) {
|
||||
// render all the properties and invoke lazy loading if required
|
||||
BeanProperty[] props = desc.propertiesNonTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
@SuppressWarnings("unchecked")
|
||||
public void write(WriteJson writeJson) {
|
||||
|
||||
try {
|
||||
BeanProperty beanProp = desc.getIdProperty();
|
||||
if (beanProp != null) {
|
||||
if (isIncludeProperty(beanProp)) {
|
||||
beanProp.jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
props = desc.propertiesTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeTransientProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
|
||||
if (!isReferenceOnly()) {
|
||||
// render all the properties and invoke lazy loading if required
|
||||
BeanProperty[] props = desc.propertiesNonTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
props = desc.propertiesTransient();
|
||||
for (int j = 0; j < props.length; j++) {
|
||||
if (isIncludeTransientProperty(props[j])) {
|
||||
props[j].jsonWrite(writeJson, currentBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (visitor != null) {
|
||||
visitor.visit(currentBean, writeJson);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Boolean includeMany(String key) {
|
||||
if (pathProperties != null) {
|
||||
String fullPath = pathStack.peekFullPath(key);
|
||||
@@ -287,15 +510,19 @@ public class WriteJson implements JsonWriter {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void toJson(String name, Collection<?> c) throws IOException {
|
||||
public void toJson(String name, Collection<?> c) {
|
||||
|
||||
beginAssocMany(name);
|
||||
try {
|
||||
beginAssocMany(name);
|
||||
|
||||
for (Object bean : c) {
|
||||
BeanDescriptor<?> d = getDescriptor(bean.getClass());
|
||||
d.jsonWrite(this, (EntityBean)bean, null);
|
||||
for (Object bean : c) {
|
||||
BeanDescriptor<?> d = getDescriptor(bean.getClass());
|
||||
d.jsonWrite(this, (EntityBean) bean, null);
|
||||
}
|
||||
endAssocMany();
|
||||
} catch (IOException e) {
|
||||
throw new JsonIOException(e);
|
||||
}
|
||||
endAssocMany();
|
||||
}
|
||||
|
||||
private <T> BeanDescriptor<T> getDescriptor(Class<T> cls) {
|
||||
@@ -306,36 +533,5 @@ public class WriteJson implements JsonWriter {
|
||||
return d;
|
||||
}
|
||||
|
||||
public void beginAssocMany(String key) throws IOException {
|
||||
pathStack.pushPathKey(key);
|
||||
generator.writeFieldName(key);
|
||||
generator.writeStartArray();
|
||||
}
|
||||
|
||||
public void endAssocMany() throws IOException {
|
||||
pathStack.pop();
|
||||
generator.writeEndArray();
|
||||
}
|
||||
|
||||
public void writeStartArray(String key) throws IOException {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartArray();
|
||||
}
|
||||
|
||||
public void writeStartObject(String key) throws IOException {
|
||||
if (key != null) {
|
||||
generator.writeFieldName(key);
|
||||
}
|
||||
generator.writeStartObject();
|
||||
}
|
||||
|
||||
public void writeEndObject() throws IOException {
|
||||
generator.writeEndObject();
|
||||
}
|
||||
|
||||
public void writeEndArray() throws IOException {
|
||||
generator.writeEndArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Wraps an underlying JsonGenerator taking into account null suppression and exposing isIncludeEmpty() etc.
|
||||
*/
|
||||
public interface JsonWriter {
|
||||
|
||||
/**
|
||||
* Return the Jackson core JsonGenerator.
|
||||
*/
|
||||
JsonGenerator gen();
|
||||
|
||||
/**
|
||||
* Return true if null values should be included in JSON output.
|
||||
*/
|
||||
boolean isIncludeNull();
|
||||
|
||||
/**
|
||||
* Return true if empty collections should be included in the JSON output.
|
||||
*/
|
||||
boolean isIncludeEmpty();
|
||||
|
||||
/**
|
||||
* Write the field name.
|
||||
*/
|
||||
void writeFieldName(String name) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a null value taking into account null value suppression.
|
||||
*/
|
||||
void writeNullField(String name) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, int value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Short value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Long value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Double value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, Float value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a number field.
|
||||
*/
|
||||
void writeNumberField(String name, BigDecimal value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a sting field.
|
||||
*/
|
||||
void writeStringField(String name, String value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinary(InputStream is, int length) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a binary field.
|
||||
*/
|
||||
void writeBinaryField(String name, byte[] value) throws IOException;
|
||||
|
||||
/**
|
||||
* Write a boolean field.
|
||||
*/
|
||||
void writeBooleanField(String name, Boolean value) throws IOException;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.StringFormatter;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.EJson;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.type;
|
||||
import com.avaje.ebean.config.dbplatform.DbType;
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.EJson;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.type;
|
||||
|
||||
import com.avaje.ebean.text.TextException;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
|
||||
@@ -26,6 +26,10 @@ public class ArrayStack<E> {
|
||||
this.list = new ArrayList<E>();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return list.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes an item onto the top of this stack.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.avaje.ebeaninternal.server.text.json;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
import com.avaje.ebean.text.json.JsonWriteBeanVisitor;
|
||||
import com.avaje.ebean.text.json.JsonWriteOptions;
|
||||
import com.avaje.ebean.text.json.JsonWriter;
|
||||
import com.avaje.tests.model.basic.Address;
|
||||
import com.avaje.tests.model.basic.Contact;
|
||||
import com.avaje.tests.model.basic.Country;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestJsonWriteVisitor extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
List<Customer> list = Ebean.find(Customer.class)
|
||||
.select("id, name, status")
|
||||
.fetch("billingAddress", "line1, city")
|
||||
.fetch("billingAddress.country", "*")
|
||||
.fetch("contacts", "firstName,email")
|
||||
.order().desc("id")
|
||||
.findList();
|
||||
|
||||
JsonContext json = Ebean.json();
|
||||
|
||||
JsonWriteOptions options = new JsonWriteOptions();
|
||||
options.setRootPathVisitor(new CustomerVisitor());
|
||||
options.setPathVisitor("billingAddress", new BillingVisitor());
|
||||
options.setPathVisitor("billingAddress.country", new CountryVisitor());
|
||||
options.setPathVisitor("contacts", new ContactVisitor());
|
||||
|
||||
String jsonContent = json.toJson(list, options);
|
||||
System.out.println(jsonContent);
|
||||
|
||||
assertThat(jsonContent).contains("customerExtra");
|
||||
assertThat(jsonContent).contains("contactExtra");
|
||||
assertThat(jsonContent).contains("billingExtra");
|
||||
assertThat(jsonContent).contains("countryExtra");
|
||||
}
|
||||
|
||||
class CustomerVisitor implements JsonWriteBeanVisitor<Customer> {
|
||||
|
||||
@Override
|
||||
public void visit(Customer bean, JsonWriter jsonWriter) {
|
||||
jsonWriter.writeStringField("customerExtra", "extra4");
|
||||
jsonWriter.writeStartObject("startObj");
|
||||
jsonWriter.writeBooleanField("yesno", true);
|
||||
jsonWriter.writeEndObject();
|
||||
|
||||
jsonWriter.writeFieldName("secObj");
|
||||
jsonWriter.writeStartObject();
|
||||
jsonWriter.writeBooleanField("yesno", false);
|
||||
jsonWriter.writeEndObject();
|
||||
|
||||
jsonWriter.writeStartArray("startList");
|
||||
jsonWriter.writeBoolean(true);
|
||||
jsonWriter.writeString("one");
|
||||
jsonWriter.writeNumber(1);
|
||||
jsonWriter.writeNumber(2L);
|
||||
jsonWriter.writeNumber(new BigDecimal("34.45"));
|
||||
jsonWriter.writeNull();
|
||||
jsonWriter.writeEndArray();
|
||||
|
||||
jsonWriter.writeFieldName("secondList");
|
||||
jsonWriter.writeStartArray();
|
||||
jsonWriter.writeNumber(3L);
|
||||
jsonWriter.writeRawValue("\"rawVal\"");
|
||||
jsonWriter.writeEndArray();
|
||||
|
||||
jsonWriter.writeRaw(",\"rawField\":{\"ra\":42}");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ContactVisitor implements JsonWriteBeanVisitor<Contact> {
|
||||
|
||||
@Override
|
||||
public void visit(Contact bean, JsonWriter jsonWriter) {
|
||||
jsonWriter.writeStringField("contactExtra", "extra3");
|
||||
}
|
||||
}
|
||||
|
||||
class BillingVisitor implements JsonWriteBeanVisitor<Address> {
|
||||
|
||||
@Override
|
||||
public void visit(Address bean, JsonWriter jsonWriter) {
|
||||
jsonWriter.writeStringField("billingExtra", "extra1");
|
||||
}
|
||||
}
|
||||
|
||||
class CountryVisitor implements JsonWriteBeanVisitor<Country> {
|
||||
|
||||
@Override
|
||||
public void visit(Country bean, JsonWriter jsonWriter) {
|
||||
jsonWriter.writeStringField("countryExtra", "extra2");
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package com.avaje.ebeaninternal.server.text.json;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
import com.avaje.ebean.text.json.JsonReadBeanVisitor;
|
||||
import com.avaje.ebean.text.json.JsonReadOptions;
|
||||
import com.avaje.tests.model.basic.Address;
|
||||
import com.avaje.tests.model.basic.Contact;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestTextJsonBeanReadVisitor extends BaseTestCase {
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
List<Customer> list = Ebean.find(Customer.class)
|
||||
.select("id, name, status, shippingAddress")
|
||||
.fetch("billingAddress", "line1, city")
|
||||
.fetch("billingAddress.country", "*")
|
||||
.fetch("contacts", "firstName,email")
|
||||
.order().desc("id")
|
||||
.findList();
|
||||
|
||||
JsonContext json = Ebean.json();
|
||||
|
||||
JsonReadOptions options = new JsonReadOptions();
|
||||
options.addRootVisitor(new CVisitor());
|
||||
options.addVisitor("contacts", new ContactVisitor());
|
||||
options.addVisitor("billingAddress", new AVisitor());
|
||||
options.addVisitor("shippingAddress", new ASVisitor());
|
||||
|
||||
String s = json.toJson(list);
|
||||
System.out.println(s);
|
||||
|
||||
List<Customer> mList = json.toList(Customer.class, s, options);
|
||||
System.out.println("VIA STRING: " + mList);
|
||||
|
||||
StringReader reader = new StringReader(s);
|
||||
List<Customer> mList2 = json.toList(Customer.class, reader);
|
||||
System.out.println("VIA READER: " + mList2);
|
||||
|
||||
assertEquals(mList.size(), mList2.size());
|
||||
}
|
||||
|
||||
private static class CVisitor implements JsonReadBeanVisitor<Customer> {
|
||||
|
||||
@Override
|
||||
public void visit(Customer bean, Map<String, Object> unmapped) {
|
||||
System.out.println("visit customer: " + bean);
|
||||
}
|
||||
}
|
||||
|
||||
private static class AVisitor implements JsonReadBeanVisitor<Address> {
|
||||
|
||||
public void visit(Address bean, Map<String, Object> unmapped) {
|
||||
System.out.println("visit billing address: " + bean);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ASVisitor implements JsonReadBeanVisitor<Address> {
|
||||
|
||||
public void visit(Address bean, Map<String, Object> unmapped) {
|
||||
System.out.println("visit shipping address: " + bean);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ContactVisitor implements JsonReadBeanVisitor<Contact> {
|
||||
|
||||
public void visit(Contact bean, Map<String, Object> unmapped) {
|
||||
System.out.println("visit contact: " + bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class WriteJsonTest {
|
||||
JsonGenerator generator = jsonFactory.createGenerator(new StringWriter());
|
||||
|
||||
PathProperties pathProperties = PathProperties.parse("id,status,name,customer(id,name,address(street,city)),orders(qty,product(sku,prodName))");
|
||||
WriteJson writeJson = new WriteJson(null, generator, pathProperties, null, JsonConfig.Include.ALL);
|
||||
WriteJson writeJson = new WriteJson(null, generator, pathProperties, null, null, JsonConfig.Include.ALL);
|
||||
|
||||
WriteJson.WriteBean rootLevel = writeJson.createWriteBean(null, null);
|
||||
assertTrue(rootLevel.currentIncludeProps.contains("id"));
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
[
|
||||
{
|
||||
"id": 4,
|
||||
"status": "ACTIVE",
|
||||
"name": "NocCust",
|
||||
"billingAddress": {
|
||||
"id": 5,
|
||||
"line1": "Bos town",
|
||||
"city": "Auckland",
|
||||
"country": {
|
||||
"code": "NZ",
|
||||
"name": "New Zealand",
|
||||
"countryExtra": "extra2"
|
||||
},
|
||||
"billingExtra": "extra1"
|
||||
},
|
||||
"contacts": [
|
||||
{
|
||||
"id": 10,
|
||||
"firstName": "Jim1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"firstName": "Fred1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"firstName": "Bugs1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
}
|
||||
],
|
||||
"selected": null,
|
||||
"customerExtra": "extra4",
|
||||
"startObj": {
|
||||
"yesno": true
|
||||
},
|
||||
"secObj": {
|
||||
"yesno": false
|
||||
},
|
||||
"startList": [
|
||||
true,
|
||||
"one",
|
||||
1,
|
||||
2,
|
||||
34.45,
|
||||
null
|
||||
],
|
||||
"secondList": [
|
||||
3,
|
||||
"rawVal"
|
||||
],
|
||||
"rawField": {
|
||||
"ra": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"status": "ACTIVE",
|
||||
"name": "Fiona",
|
||||
"billingAddress": {
|
||||
"id": 3,
|
||||
"line1": "West Coast Rd",
|
||||
"city": "Auckland",
|
||||
"country": {
|
||||
"code": "NZ",
|
||||
"name": "New Zealand",
|
||||
"countryExtra": "extra2"
|
||||
},
|
||||
"billingExtra": "extra1"
|
||||
},
|
||||
"contacts": [
|
||||
{
|
||||
"id": 5,
|
||||
"firstName": "Jim1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"firstName": "Fred1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"firstName": "Bugs1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"firstName": "Fiona",
|
||||
"email": "black2@test.com",
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"firstName": "Tracy",
|
||||
"email": "red3@test.com",
|
||||
"contactExtra": "extra3"
|
||||
}
|
||||
],
|
||||
"selected": null,
|
||||
"customerExtra": "extra4",
|
||||
"startObj": {
|
||||
"yesno": true
|
||||
},
|
||||
"secObj": {
|
||||
"yesno": false
|
||||
},
|
||||
"startList": [
|
||||
true,
|
||||
"one",
|
||||
1,
|
||||
2,
|
||||
34.45,
|
||||
null
|
||||
],
|
||||
"secondList": [
|
||||
3,
|
||||
"rawVal"
|
||||
],
|
||||
"rawField": {
|
||||
"ra": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"status": "NEW",
|
||||
"name": "Cust NoAddress",
|
||||
"billingAddress": null,
|
||||
"contacts": [
|
||||
{
|
||||
"id": 4,
|
||||
"firstName": "Jack",
|
||||
"email": "black1@test.com",
|
||||
"contactExtra": "extra3"
|
||||
}
|
||||
],
|
||||
"selected": null,
|
||||
"customerExtra": "extra4",
|
||||
"startObj": {
|
||||
"yesno": true
|
||||
},
|
||||
"secObj": {
|
||||
"yesno": false
|
||||
},
|
||||
"startList": [
|
||||
true,
|
||||
"one",
|
||||
1,
|
||||
2,
|
||||
34.45,
|
||||
null
|
||||
],
|
||||
"secondList": [
|
||||
3,
|
||||
"rawVal"
|
||||
],
|
||||
"rawField": {
|
||||
"ra": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"status": "NEW",
|
||||
"name": "Rob",
|
||||
"billingAddress": {
|
||||
"id": 1,
|
||||
"line1": "P.O.Box 1234",
|
||||
"city": "Auckland",
|
||||
"country": {
|
||||
"code": "NZ",
|
||||
"name": "New Zealand",
|
||||
"countryExtra": "extra2"
|
||||
},
|
||||
"billingExtra": "extra1"
|
||||
},
|
||||
"contacts": [
|
||||
{
|
||||
"id": 1,
|
||||
"firstName": "Jim1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"firstName": "Fred1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"firstName": "Bugs1",
|
||||
"email": null,
|
||||
"contactExtra": "extra3"
|
||||
}
|
||||
],
|
||||
"selected": null,
|
||||
"customerExtra": "extra4",
|
||||
"startObj": {
|
||||
"yesno": true
|
||||
},
|
||||
"secObj": {
|
||||
"yesno": false
|
||||
},
|
||||
"startList": [
|
||||
true,
|
||||
"one",
|
||||
1,
|
||||
2,
|
||||
34.45,
|
||||
null
|
||||
],
|
||||
"secondList": [
|
||||
3,
|
||||
"rawVal"
|
||||
],
|
||||
"rawField": {
|
||||
"ra": 42
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user